items draw rework, npc trade fix
This commit is contained in:
parent
7b512bfa9f
commit
1203756baf
|
@ -210,10 +210,10 @@ local function onOpenNpcTrade(items)
|
|||
newItem.name = item[2]
|
||||
newItem.weight = item[3] / 100
|
||||
|
||||
if item[4] >= 0 then
|
||||
if item[4] > 0 then
|
||||
newItem.price = item[4]
|
||||
table.insert(tradeItems[BUY], newItem)
|
||||
elseif item[5] >= 0 then
|
||||
elseif item[5] > 0 then
|
||||
newItem.price = item[5]
|
||||
table.insert(tradeItems[SELL], newItem)
|
||||
else
|
||||
|
|
|
@ -13,7 +13,7 @@ SET(BUILD_REVISION "custom" CACHE "Git revision string (intended for releases)"
|
|||
|
||||
# set debug as default build type
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
SET(CMAKE_BUILD_TYPE Debug)
|
||||
ENDIF()
|
||||
|
||||
# setup compiler options
|
||||
|
|
|
@ -83,3 +83,23 @@ void Image::overwriteMask(const Color& maskedColor, const Color& insideColor, co
|
|||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
static ImagePtr loadPNG(const std::string& file);
|
||||
|
||||
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; }
|
||||
uint8* getPixelData() { return &m_pixels[0]; }
|
||||
|
@ -43,6 +44,7 @@ public:
|
|||
int getWidth() { return m_size.width(); }
|
||||
int getHeight() { return m_size.height(); }
|
||||
int getBpp() { return m_bpp; }
|
||||
uint8* getPixel(int x, int y) { return &m_pixels[(y * m_size.width() + x) * 4]; }
|
||||
|
||||
private:
|
||||
std::vector<uint8> m_pixels;
|
||||
|
|
|
@ -142,6 +142,7 @@ void Texture::generateMipmaps()
|
|||
//FIXME: disabled because mipmaps size needs to be in base of 2,
|
||||
// and the current algorithmn does not support that
|
||||
//generateSoftwareMipmaps(getPixels());
|
||||
logTraceError("non power of 2.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,7 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
|
|||
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 w = 0; w < getDimensionWidth(); w++) {
|
||||
// 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;
|
||||
m_type->draw(p, scaleFactor, w, h, xPattern, yPattern, zPattern, 0, animationPhase);
|
||||
|
||||
if(getLayers() > 1) {
|
||||
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)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ void Effect::draw(const Point& dest, float scaleFactor, bool animate)
|
|||
int animationPhase = 0;
|
||||
if(animate)
|
||||
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()
|
||||
|
|
|
@ -181,7 +181,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
|||
*/
|
||||
|
||||
// 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
|
||||
g_painter->resetShaderProgram();
|
||||
|
|
|
@ -63,7 +63,7 @@ void Missile::draw(const Point& dest, float scaleFactor, bool animate)
|
|||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -48,6 +48,7 @@ bool ThingsType::load(const std::string& file)
|
|||
for(int i = 0; i < LastCategory; ++i) {
|
||||
m_things[i].resize(numThings[i]);
|
||||
for(int id = 0; id < numThings[i]; ++id) {
|
||||
m_things[i][id].m_category = i;
|
||||
if(!parseThingType(fin, m_things[i][id])) {
|
||||
logError("corrupt or dat file");
|
||||
return false;
|
||||
|
@ -142,10 +143,13 @@ bool ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType)
|
|||
return false;
|
||||
|
||||
thingType.m_spritesIndex.resize(totalSprites);
|
||||
thingType.m_sprites.resize(totalSprites);
|
||||
for(int i = 0; i < totalSprites; i++)
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "thingtype.h"
|
||||
#include "thingstype.h"
|
||||
#include "spritemanager.h"
|
||||
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
@ -34,23 +35,20 @@ ThingType::ThingType()
|
|||
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]);
|
||||
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->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);
|
||||
g_painter->drawTexturedRect(screenRect, texture, textureRect);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -108,3 +86,103 @@ TexturePtr& ThingType::getSpriteMask(int w, int h, int l, int x, int y, int z, i
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#define THINGATTRIBUTES_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
#include <framework/graphics/declarations.h>
|
||||
#include <framework/graphics/coordsbuffer.h>
|
||||
|
||||
struct ThingType
|
||||
{
|
||||
|
@ -108,18 +108,20 @@ struct 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 xPattern, int yPattern, int zPattern, int animationPhase);
|
||||
void draw(const Point& dest, float scaleFactor, int layer, 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);
|
||||
|
||||
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& getTexture(int animationPhase);
|
||||
|
||||
bool getProperty(Property property) { return m_properties[property]; }
|
||||
int getParameter(Parameter param) { return m_parameters[param]; }
|
||||
int getDimension(Dimension dimension) { return m_dimensions[dimension]; }
|
||||
|
||||
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 index = ((((((a % m_dimensions[ThingType::AnimationPhases])
|
||||
* m_dimensions[ThingType::PatternZ] + z)
|
||||
|
@ -128,17 +130,28 @@ private:
|
|||
* m_dimensions[ThingType::Layers] + l)
|
||||
* m_dimensions[ThingType::Height] + h)
|
||||
* m_dimensions[ThingType::Width] + w;
|
||||
assert(index < m_sprites.size());
|
||||
assert(index < m_spritesIndex.size());
|
||||
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, LastParameter> m_parameters;
|
||||
std::array<bool, LastProperty> m_properties;
|
||||
std::vector<int> m_spritesIndex;
|
||||
std::vector<TexturePtr> m_sprites;
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ void UIItem::drawSelf()
|
|||
g_painter->setColor(Color(231, 231, 231));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue