rename item count to countOrSubType, rework and improve things animation/drawing
This commit is contained in:
parent
edeee80631
commit
ef96215421
|
@ -30,14 +30,14 @@ function UIItem:onDrop(widget, mousePos)
|
|||
if not widget or not widget.currentDragThing then return true end
|
||||
|
||||
local pos = self.position
|
||||
local data = widget.currentDragThing:getCount()
|
||||
if widget.currentDragThing:isStackable() and data > 1 then
|
||||
local count = widget.currentDragThing:getCount()
|
||||
if widget.currentDragThing:isStackable() and count > 1 then
|
||||
widget.parsed = true
|
||||
local moveWindow = displayUI('/game/movewindow.otui')
|
||||
local spinbox = moveWindow:getChildById('spinbox')
|
||||
spinbox:setMaximum(data)
|
||||
spinbox:setMaximum(count)
|
||||
spinbox:setMinimum(1)
|
||||
spinbox:setCurrentIndex(data)
|
||||
spinbox:setCurrentIndex(count)
|
||||
|
||||
local okButton = moveWindow:getChildById('buttonOk')
|
||||
okButton.onClick = function() Game.move(widget.currentDragThing, pos, spinbox:getCurrentIndex()) okButton:getParent():destroy() widget.currentDragThing = nil end
|
||||
|
|
|
@ -15,7 +15,7 @@ function UIMap:onDragLeave(widget, mousePos)
|
|||
if not self.parsed then
|
||||
self.currentDragThing = nil
|
||||
end
|
||||
|
||||
|
||||
restoreCursor()
|
||||
return true
|
||||
end
|
||||
|
@ -25,16 +25,16 @@ function UIMap:onDrop(widget, mousePos)
|
|||
|
||||
local tile = self:getTile(mousePos)
|
||||
if not tile then return false end
|
||||
|
||||
local data = widget.currentDragThing:getCount()
|
||||
|
||||
local count = widget.currentDragThing:getCount()
|
||||
if widget.currentDragThing:isStackable() and data > 1 then
|
||||
widget.parsed = true
|
||||
local moveWindow = displayUI('/game/movewindow.otui')
|
||||
local spinbox = moveWindow:getChildById('spinbox')
|
||||
spinbox:setMaximum(data)
|
||||
spinbox:setMaximum(count)
|
||||
spinbox:setMinimum(1)
|
||||
spinbox:setCurrentIndex(data)
|
||||
|
||||
spinbox:setCurrentIndex(count)
|
||||
|
||||
local okButton = moveWindow:getChildById('buttonOk')
|
||||
okButton.onClick = function() Game.move(widget.currentDragThing, tile:getPosition(), spinbox:getCurrentIndex()) okButton:getParent():destroy() widget.currentDragThing = nil end
|
||||
moveWindow.onEnter = okButton.onClick
|
||||
|
|
|
@ -6,6 +6,5 @@ varying vec2 textureCoords; // map texture coords
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 outColor = texture2D(texture, textureCoords) * opacity;
|
||||
gl_FragColor = outColor;
|
||||
gl_FragColor = texture2D(texture, textureCoords) * opacity;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace Otc
|
|||
AWARE_Y_BOTTOM_TILES = AWARE_Y_TILES/2,
|
||||
|
||||
EFFECT_TICKS_PER_FRAME = 75,
|
||||
INVISIBLE_TICKS_PER_FRAME = 500,
|
||||
ITEM_TICKS_PER_FRAME = 500,
|
||||
ANIMATED_TEXT_DURATION = 1000,
|
||||
STATIC_DURATION_PER_CHARACTER = 75,
|
||||
|
@ -66,9 +67,11 @@ namespace Otc
|
|||
DrawCreaturesInformation = 64,
|
||||
DrawStaticTexts = 128,
|
||||
DrawAnimatedTexts = 256,
|
||||
DrawEverything = DrawGround | DrawWalls | DrawCommonItems |
|
||||
DrawAnimations = 512,
|
||||
DrawGroundBorders = 1024,
|
||||
DrawEverything = DrawGround | DrawGroundBorders | DrawWalls | DrawCommonItems |
|
||||
DrawCreatures | DrawEffects | DrawMissiles |
|
||||
DrawCreaturesInformation | DrawStaticTexts | DrawAnimatedTexts
|
||||
DrawCreaturesInformation | DrawStaticTexts | DrawAnimatedTexts | DrawAnimations
|
||||
};
|
||||
|
||||
enum DatOpts {
|
||||
|
|
|
@ -44,6 +44,7 @@ Creature::Creature() : Thing()
|
|||
m_showVolatileSquare = false;
|
||||
m_showStaticSquare = false;
|
||||
m_direction = Otc::South;
|
||||
m_walkAnimationPhase = 0;
|
||||
m_walking = false;
|
||||
m_walkInterval = 0;
|
||||
m_walkAnimationInterval = 0;
|
||||
|
@ -63,18 +64,20 @@ int LEGS_COLOR_UNIFORM = 12;
|
|||
int FEET_COLOR_UNIFORM = 13;
|
||||
int MASK_TEXTURE_UNIFORM = 14;
|
||||
|
||||
void Creature::draw(const Point& dest, float scaleFactor)
|
||||
void Creature::draw(const Point& dest, float scaleFactor, bool animate)
|
||||
{
|
||||
int scaledTileSize = Otc::TILE_PIXELS * scaleFactor;
|
||||
|
||||
if(m_showVolatileSquare) {
|
||||
Point animationOffset = animate ? m_walkOffset : Point(0,0);
|
||||
|
||||
if(m_showVolatileSquare && animate) {
|
||||
g_painter.setColor(m_volatileSquareColor);
|
||||
g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - 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*scaleFactor, 28*scaleFactor)), std::max((int)(2*scaleFactor), 1));
|
||||
}
|
||||
|
||||
if(m_showStaticSquare) {
|
||||
if(m_showStaticSquare && animate) {
|
||||
g_painter.setColor(m_staticSquareColor);
|
||||
g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 1)*scaleFactor, Size(scaledTileSize, scaledTileSize)), std::max((int)(2*scaleFactor), 1));
|
||||
g_painter.drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 1)*scaleFactor, Size(scaledTileSize, scaledTileSize)), std::max((int)(2*scaleFactor), 1));
|
||||
}
|
||||
|
||||
g_painter.setColor(Fw::white);
|
||||
|
@ -90,12 +93,25 @@ void Creature::draw(const Point& dest, float scaleFactor)
|
|||
outfitProgram->bindUniformLocation(MASK_TEXTURE_UNIFORM, "maskTexture");
|
||||
}
|
||||
|
||||
// Render creature
|
||||
int xPattern = 0, yPattern = 0, zPattern = 0;
|
||||
|
||||
// outfit is a real creature
|
||||
if(m_outfit.getCategory() == ThingsType::Creature) {
|
||||
for(m_yPattern = 0; m_yPattern < getNumPatternsY(); m_yPattern++) {
|
||||
int animationPhase = animate ? m_walkAnimationPhase : 0;
|
||||
|
||||
// xPattern => creature direction
|
||||
if(m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
|
||||
xPattern = Otc::East;
|
||||
else if(m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
|
||||
xPattern = Otc::West;
|
||||
else
|
||||
xPattern = m_direction;
|
||||
|
||||
// yPattern => creature addon
|
||||
for(yPattern = 0; yPattern < getNumPatternsY(); yPattern++) {
|
||||
|
||||
// continue if we dont have this addon.
|
||||
if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
|
||||
if(yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern-1))))
|
||||
continue;
|
||||
|
||||
g_painter.setCustomProgram(outfitProgram);
|
||||
|
@ -108,22 +124,23 @@ void Creature::draw(const Point& dest, float scaleFactor)
|
|||
|
||||
for(int h = 0; h < getDimensionHeight(); h++) {
|
||||
for(int w = 0; w < getDimensionWidth(); w++) {
|
||||
int spriteId = getSpriteId(w, h, 0, m_xPattern, m_yPattern, m_zPattern, m_animation);
|
||||
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) {
|
||||
int maskId = getSpriteId(w, h, 1, m_xPattern, m_yPattern, m_zPattern, m_animation);
|
||||
int maskId = getSpriteId(w, h, 1, xPattern, yPattern, zPattern, m_walkAnimationPhase);
|
||||
maskTex = g_sprites.getSpriteTexture(maskId);
|
||||
}
|
||||
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
|
||||
|
||||
Rect drawRect(dest.x + (m_walkOffset.x - w*Otc::TILE_PIXELS - getDisplacementX())*scaleFactor,
|
||||
dest.y + (m_walkOffset.y - h*Otc::TILE_PIXELS - getDisplacementY())*scaleFactor,
|
||||
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);
|
||||
}
|
||||
|
@ -131,13 +148,32 @@ void Creature::draw(const Point& dest, float scaleFactor)
|
|||
|
||||
g_painter.releaseCustomProgram();
|
||||
}
|
||||
// outfit is a creature imitating an item or the invisible effect
|
||||
} else {
|
||||
int animationPhase = 0;
|
||||
int animationPhases = getAnimationPhases();
|
||||
int animateTicks = Otc::ITEM_TICKS_PER_FRAME;
|
||||
|
||||
// when creature is an effect we cant render the first and last animation phase,
|
||||
// instead we should loop in the phases between
|
||||
if(m_outfit.getCategory() == ThingsType::Effect) {
|
||||
animationPhases = std::max(1, animationPhases-2);
|
||||
animateTicks = Otc::INVISIBLE_TICKS_PER_FRAME;
|
||||
}
|
||||
|
||||
if(animationPhases > 1) {
|
||||
if(animate)
|
||||
animationPhase = (g_clock.ticks() % (animateTicks * animationPhases)) / animateTicks;
|
||||
else
|
||||
animationPhase = animationPhases-1;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else if(m_outfit.getCategory() == ThingsType::Item) {
|
||||
for(int l = 0; l < getLayers(); l++)
|
||||
internalDraw(dest + m_walkOffset, scaleFactor, l);
|
||||
}
|
||||
else if(m_outfit.getCategory() == ThingsType::Effect)
|
||||
internalDraw(dest + m_walkOffset, scaleFactor, 0);
|
||||
}
|
||||
|
||||
void Creature::drawInformation(const Point& point, bool useGray, const Rect& parentRect)
|
||||
|
@ -244,7 +280,7 @@ void Creature::stopWalk()
|
|||
|
||||
// reset walk animation states
|
||||
m_walkOffset = Point(0,0);
|
||||
m_animation = 0;
|
||||
m_walkAnimationPhase = 0;
|
||||
|
||||
// stops the walk right away
|
||||
terminateWalk();
|
||||
|
@ -257,9 +293,9 @@ void Creature::updateWalkAnimation(int totalPixelsWalked)
|
|||
return;
|
||||
|
||||
if(totalPixelsWalked == 32 || totalPixelsWalked == 0 || getAnimationPhases() <= 1)
|
||||
m_animation = 0;
|
||||
m_walkAnimationPhase = 0;
|
||||
else if(getAnimationPhases() > 1)
|
||||
m_animation = 1 + ((totalPixelsWalked * 4) / Otc::TILE_PIXELS) % (getAnimationPhases() - 1);
|
||||
m_walkAnimationPhase = 1 + ((totalPixelsWalked * 4) / Otc::TILE_PIXELS) % (getAnimationPhases() - 1);
|
||||
}
|
||||
|
||||
void Creature::updateWalkOffset(int totalPixelsWalked)
|
||||
|
@ -402,40 +438,13 @@ void Creature::setHealthPercent(uint8 healthPercent)
|
|||
|
||||
void Creature::setDirection(Otc::Direction direction)
|
||||
{
|
||||
if(m_outfit.getCategory() == ThingsType::Creature) {
|
||||
if(direction == Otc::NorthEast || direction == Otc::SouthEast)
|
||||
m_xPattern = Otc::East;
|
||||
else if(direction == Otc::NorthWest || direction == Otc::SouthWest)
|
||||
m_xPattern = Otc::West;
|
||||
else
|
||||
m_xPattern = direction;
|
||||
} else {
|
||||
m_xPattern = 0;
|
||||
}
|
||||
|
||||
m_direction = direction;
|
||||
}
|
||||
|
||||
void Creature::setOutfit(const Outfit& outfit)
|
||||
{
|
||||
m_outfit = outfit;
|
||||
updateType();
|
||||
m_animation = 0;
|
||||
|
||||
if(m_outfit.getCategory() == ThingsType::Effect) {
|
||||
updateInvisibleAnimation();
|
||||
|
||||
m_xPattern = 0;
|
||||
m_yPattern = 0;
|
||||
}
|
||||
if(m_outfit.getCategory() == ThingsType::Item) {
|
||||
m_xPattern = 0;
|
||||
m_yPattern = 0;
|
||||
}
|
||||
|
||||
if(m_outfit.getCategory() == ThingsType::Creature && getLayers() == 1) {
|
||||
m_outfit.resetClothes();
|
||||
}
|
||||
m_type = g_thingsType.getThingType(outfit.getId(), outfit.getCategory());
|
||||
}
|
||||
|
||||
void Creature::setSkull(uint8 skull)
|
||||
|
@ -493,26 +502,6 @@ void Creature::addVolatileSquare(uint8 color)
|
|||
}, VOLATILE_SQUARE_DURATION);
|
||||
}
|
||||
|
||||
void Creature::updateInvisibleAnimation()
|
||||
{
|
||||
if(!g_game.isOnline() || m_outfit.getCategory() != ThingsType::Effect)
|
||||
return;
|
||||
|
||||
if(m_animation == 1)
|
||||
m_animation = 2;
|
||||
else if(m_animation == 2)
|
||||
m_animation = 3;
|
||||
else if(m_animation == 3)
|
||||
m_animation = 1;
|
||||
else
|
||||
m_animation = 1;
|
||||
|
||||
auto self = asCreature();
|
||||
g_dispatcher.scheduleEvent([self]() {
|
||||
self->updateInvisibleAnimation();
|
||||
}, INVISIBLE_TICKS);
|
||||
}
|
||||
|
||||
void Creature::updateShield()
|
||||
{
|
||||
m_showShieldTexture = !m_showShieldTexture;
|
||||
|
|
|
@ -34,16 +34,16 @@ class Creature : public Thing
|
|||
public:
|
||||
enum {
|
||||
SHIELD_BLINK_TICKS = 500,
|
||||
INVISIBLE_TICKS = 500,
|
||||
VOLATILE_SQUARE_DURATION = 1000
|
||||
};
|
||||
|
||||
Creature();
|
||||
virtual ~Creature() { }
|
||||
|
||||
virtual void draw(const Point& dest, float scaleFactor);
|
||||
virtual void draw(const Point& dest, float scaleFactor, bool animate);
|
||||
void drawInformation(const Point& point, bool useGray, const Rect& parentRect);
|
||||
|
||||
void setId(uint32 id) { m_id = id; }
|
||||
void setName(const std::string& name);
|
||||
void setHealthPercent(uint8 healthPercent);
|
||||
void setDirection(Otc::Direction direction);
|
||||
|
@ -64,6 +64,7 @@ public:
|
|||
void showStaticSquare(const Color& color) { m_showStaticSquare = true; m_staticSquareColor = color; }
|
||||
void hideStaticSquare() { m_showStaticSquare = false; }
|
||||
|
||||
uint32 getId() { return m_id; }
|
||||
std::string getName() { return m_name; }
|
||||
uint8 getHealthPercent() { return m_healthPercent; }
|
||||
Otc::Direction getDirection() { return m_direction; }
|
||||
|
@ -96,6 +97,7 @@ protected:
|
|||
virtual void updateWalk();
|
||||
virtual void terminateWalk();
|
||||
|
||||
uint32 m_id;
|
||||
std::string m_name;
|
||||
Size m_nameSize;
|
||||
uint8 m_healthPercent;
|
||||
|
@ -114,6 +116,7 @@ protected:
|
|||
Color m_informationColor;
|
||||
|
||||
// walk related
|
||||
int m_walkAnimationPhase;
|
||||
Timer m_walkTimer;
|
||||
TilePtr m_walkingTile;
|
||||
int m_walkInterval;
|
||||
|
|
|
@ -27,35 +27,27 @@
|
|||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
void Effect::draw(const Point& dest, float scaleFactor)
|
||||
void Effect::draw(const Point& dest, float scaleFactor, bool animate)
|
||||
{
|
||||
internalDraw(dest, scaleFactor, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
void Effect::startAnimation()
|
||||
{
|
||||
m_animationTimer.restart();
|
||||
|
||||
auto self = asEffect();
|
||||
|
||||
// schedule next animation update
|
||||
if(getAnimationPhases() > 1)
|
||||
g_dispatcher.scheduleEvent([self]() { self->updateAnimation(); }, Otc::EFFECT_TICKS_PER_FRAME);
|
||||
|
||||
// schedule removal
|
||||
auto self = asEffect();
|
||||
g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, Otc::EFFECT_TICKS_PER_FRAME * getAnimationPhases());
|
||||
}
|
||||
|
||||
void Effect::updateAnimation()
|
||||
void Effect::setId(uint32 id)
|
||||
{
|
||||
int animationPhase = m_animationTimer.ticksElapsed() / Otc::EFFECT_TICKS_PER_FRAME;
|
||||
|
||||
if(animationPhase < getAnimationPhases())
|
||||
m_animation = animationPhase;
|
||||
|
||||
if(animationPhase < getAnimationPhases() - 1) {
|
||||
//schedule next animation update
|
||||
auto self = asEffect();
|
||||
g_dispatcher.scheduleEvent([self]() { self->updateAnimation(); }, Otc::EFFECT_TICKS_PER_FRAME);
|
||||
}
|
||||
m_id = id;
|
||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Effect);
|
||||
}
|
||||
|
|
|
@ -30,15 +30,17 @@
|
|||
class Effect : public Thing
|
||||
{
|
||||
public:
|
||||
void draw(const Point& dest, float scaleFactor);
|
||||
void draw(const Point& dest, float scaleFactor, bool animate);
|
||||
|
||||
void setId(uint32 id);
|
||||
void startAnimation();
|
||||
void updateAnimation();
|
||||
|
||||
uint32 getId() { return m_id; }
|
||||
EffectPtr asEffect() { return std::static_pointer_cast<Effect>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
Timer m_animationTimer;
|
||||
uint16 m_id;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
|
||||
Item::Item() : Thing()
|
||||
{
|
||||
m_count = 1;
|
||||
m_id = 0;
|
||||
m_countOrSubType = 1;
|
||||
}
|
||||
|
||||
ItemPtr Item::create(int id)
|
||||
|
@ -48,11 +49,115 @@ ItemPtr Item::create(int id)
|
|||
|
||||
PainterShaderProgramPtr itemProgram;
|
||||
|
||||
void Item::draw(const Point& dest, float scaleFactor)
|
||||
void Item::draw(const Point& dest, float scaleFactor, bool animate)
|
||||
{
|
||||
if(getAnimationPhases() > 1)
|
||||
m_animation = (g_clock.ticks() % (Otc::ITEM_TICKS_PER_FRAME * getAnimationPhases())) / Otc::ITEM_TICKS_PER_FRAME;
|
||||
if(m_id == 0)
|
||||
return;
|
||||
|
||||
// determine animation phase
|
||||
int animationPhase = 0;
|
||||
if(getAnimationPhases() > 1) {
|
||||
if(animate)
|
||||
animationPhase = (g_clock.ticks() % (Otc::ITEM_TICKS_PER_FRAME * getAnimationPhases())) / Otc::ITEM_TICKS_PER_FRAME;
|
||||
else
|
||||
animationPhase = getAnimationPhases()-1;
|
||||
}
|
||||
|
||||
// determine x,y,z patterns
|
||||
int xPattern = 0, yPattern = 0, zPattern = 0;
|
||||
if(isGround()) {
|
||||
xPattern = m_position.x % getNumPatternsX();
|
||||
yPattern = m_position.y % getNumPatternsY();
|
||||
zPattern = m_position.z % getNumPatternsZ();
|
||||
} else if(isStackable() && getNumPatternsX() == 4 && getNumPatternsY() == 2) {
|
||||
if(m_countOrSubType < 5) {
|
||||
xPattern = m_countOrSubType-1;
|
||||
yPattern = 0;
|
||||
} else if(m_countOrSubType < 10) {
|
||||
xPattern = 0;
|
||||
yPattern = 1;
|
||||
} else if(m_countOrSubType < 25) {
|
||||
xPattern = 1;
|
||||
yPattern = 1;
|
||||
} else if(m_countOrSubType < 50) {
|
||||
xPattern = 2;
|
||||
yPattern = 1;
|
||||
} else if(m_countOrSubType <= 100) {
|
||||
xPattern = 3;
|
||||
yPattern = 1;
|
||||
}
|
||||
} else if(isHangable()) {
|
||||
if(isHookSouth())
|
||||
xPattern = getNumPatternsX() >= 2 ? 1 : 0;
|
||||
else if(isHookEast())
|
||||
xPattern = getNumPatternsX() >= 3 ? 2 : 0;
|
||||
} else if(isFluid() || isFluidContainer()) {
|
||||
int color = Otc::FluidTransparent;
|
||||
switch(m_countOrSubType) {
|
||||
case Otc::FluidNone:
|
||||
color = Otc::FluidTransparent;
|
||||
break;
|
||||
case Otc::FluidWater:
|
||||
color = Otc::FluidBlue;
|
||||
break;
|
||||
case Otc::FluidMana:
|
||||
color = Otc::FluidPurple;
|
||||
break;
|
||||
case Otc::FluidBeer:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidOil:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidBlood:
|
||||
color = Otc::FluidRed;
|
||||
break;
|
||||
case Otc::FluidSlime:
|
||||
color = Otc::FluidGreen;
|
||||
break;
|
||||
case Otc::FluidMud:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidLemonade:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidMilk:
|
||||
color = Otc::FluidWhite;
|
||||
break;
|
||||
case Otc::FluidWine:
|
||||
color = Otc::FluidPurple;
|
||||
break;
|
||||
case Otc::FluidHealth:
|
||||
color = Otc::FluidRed;
|
||||
break;
|
||||
case Otc::FluidUrine:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidRum:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidFruidJuice:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidCoconutMilk:
|
||||
color = Otc::FluidWhite;
|
||||
break;
|
||||
case Otc::FluidTea:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidMead:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
default:
|
||||
color = Otc::FluidTransparent;
|
||||
break;
|
||||
}
|
||||
|
||||
xPattern = (color % 4) % getNumPatternsX();
|
||||
yPattern = (color / 4) % getNumPatternsY();
|
||||
}
|
||||
|
||||
// setup item drawing shader
|
||||
if(!itemProgram) {
|
||||
itemProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
itemProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
|
@ -61,121 +166,36 @@ void Item::draw(const Point& dest, float scaleFactor)
|
|||
}
|
||||
g_painter.setCustomProgram(itemProgram);
|
||||
|
||||
// draw all item layers
|
||||
for(int layer = 0; layer < getLayers(); layer++)
|
||||
internalDraw(dest, scaleFactor, layer);
|
||||
internalDraw(dest, scaleFactor, xPattern, yPattern, zPattern, layer, animationPhase);
|
||||
|
||||
// release draw shader
|
||||
g_painter.releaseCustomProgram();
|
||||
}
|
||||
|
||||
void Item::setPosition(const Position& position)
|
||||
void Item::setId(uint32 id)
|
||||
{
|
||||
if(isGround()) {
|
||||
m_xPattern = position.x % getNumPatternsX();
|
||||
m_yPattern = position.y % getNumPatternsY();
|
||||
m_zPattern = position.z % getNumPatternsZ();
|
||||
if(id < g_thingsType.getFirstItemId() || id > g_thingsType.getMaxItemid()) {
|
||||
logTraceError("invalid item id ", id);
|
||||
return;
|
||||
}
|
||||
|
||||
Thing::setPosition(position);
|
||||
m_id = id;
|
||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Item);
|
||||
}
|
||||
|
||||
void Item::setCount(int count)
|
||||
int Item::getCount()
|
||||
{
|
||||
count = std::max(std::min(count, 255), 0);
|
||||
|
||||
if(isStackable() && getNumPatternsX() == 4 && getNumPatternsY() == 2) {
|
||||
if(count < 5) {
|
||||
m_xPattern = count-1;
|
||||
m_yPattern = 0;
|
||||
}
|
||||
else if(count < 10) {
|
||||
m_xPattern = 0;
|
||||
m_yPattern = 1;
|
||||
}
|
||||
else if(count < 25) {
|
||||
m_xPattern = 1;
|
||||
m_yPattern = 1;
|
||||
}
|
||||
else if(count < 50) {
|
||||
m_xPattern = 2;
|
||||
m_yPattern = 1;
|
||||
}
|
||||
else if(count <= 100) {
|
||||
m_xPattern = 3;
|
||||
m_yPattern = 1;
|
||||
}
|
||||
}
|
||||
else if(isHangable()) {
|
||||
if(isHookSouth()) {
|
||||
m_xPattern = getNumPatternsX() >= 2 ? 1 : 0;
|
||||
}
|
||||
else if(isHookEast()) {
|
||||
m_xPattern = getNumPatternsX() >= 3 ? 2 : 0;
|
||||
}
|
||||
}
|
||||
else if(isFluid() || isFluidContainer()) {
|
||||
int color = Otc::FluidTransparent;
|
||||
switch(count) {
|
||||
case Otc::FluidNone:
|
||||
color = Otc::FluidTransparent;
|
||||
break;
|
||||
case Otc::FluidWater:
|
||||
color = Otc::FluidBlue;
|
||||
break;
|
||||
case Otc::FluidMana:
|
||||
color = Otc::FluidPurple;
|
||||
break;
|
||||
case Otc::FluidBeer:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidOil:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidBlood:
|
||||
color = Otc::FluidRed;
|
||||
break;
|
||||
case Otc::FluidSlime:
|
||||
color = Otc::FluidGreen;
|
||||
break;
|
||||
case Otc::FluidMud:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidLemonade:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidMilk:
|
||||
color = Otc::FluidWhite;
|
||||
break;
|
||||
case Otc::FluidWine:
|
||||
color = Otc::FluidPurple;
|
||||
break;
|
||||
case Otc::FluidHealth:
|
||||
color = Otc::FluidRed;
|
||||
break;
|
||||
case Otc::FluidUrine:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidRum:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidFruidJuice:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidCoconutMilk:
|
||||
color = Otc::FluidWhite;
|
||||
break;
|
||||
case Otc::FluidTea:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidMead:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
default:
|
||||
color = Otc::FluidTransparent;
|
||||
break;
|
||||
}
|
||||
|
||||
m_xPattern = (color % 4) % getNumPatternsX();
|
||||
m_yPattern = (color / 4) % getNumPatternsY();
|
||||
}
|
||||
|
||||
m_count = count;
|
||||
if(isStackable())
|
||||
return m_countOrSubType;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Item::getSubType()
|
||||
{
|
||||
if(isFluid() || isFluidContainer())
|
||||
return m_countOrSubType;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -33,17 +33,23 @@ public:
|
|||
|
||||
static ItemPtr create(int id);
|
||||
|
||||
void draw(const Point& dest, float scaleFactor);
|
||||
void draw(const Point& dest, float scaleFactor, bool animate);
|
||||
|
||||
void setPosition(const Position &position);
|
||||
void setCount(int count);
|
||||
void setId(uint32 id);
|
||||
void setCountOrSubType(uint8 value) { m_countOrSubType = value; }
|
||||
void setCount(int count) { setCountOrSubType(count); }
|
||||
void setSubType(int subType) { setCountOrSubType(subType); }
|
||||
|
||||
int getCount() { return m_count; }
|
||||
uint8 getCountOrSubType() { return m_countOrSubType; }
|
||||
int getSubType();
|
||||
int getCount();
|
||||
uint32 getId() { return m_id; }
|
||||
|
||||
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
uint8 m_count;
|
||||
uint16 m_id;
|
||||
uint8 m_countOrSubType;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,9 +69,9 @@ void Map::load()
|
|||
while(id != 0xFFFF) {
|
||||
ItemPtr item = Item::create(id);
|
||||
if(item->isStackable() || item->isFluidContainer() || item->isFluid()) {
|
||||
uint8 data;
|
||||
in.read((char*)&data, sizeof(data));
|
||||
item->setCount(data);
|
||||
uint8 countOrSubType;
|
||||
in.read((char*)&countOrSubType, sizeof(countOrSubType));
|
||||
item->setCountOrSubType(countOrSubType);
|
||||
}
|
||||
addThing(item, pos, 255);
|
||||
in.read((char*)&id, sizeof(id));
|
||||
|
@ -95,8 +95,8 @@ void Map::save()
|
|||
id = item->getId();
|
||||
out.write((char*)&id, sizeof(id));
|
||||
if(item->isStackable() || item->isFluidContainer() || item->isFluid()) {
|
||||
uint8 data = item->getCount();
|
||||
out.write((char*)&data, sizeof(data));
|
||||
uint8 countOrSubType = item->getCountOrSubType();
|
||||
out.write((char*)&countOrSubType, sizeof(countOrSubType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ void Map::setCentralPosition(const Position& centralPosition)
|
|||
if(teleported) {
|
||||
for(const auto& pair : m_knownCreatures) {
|
||||
const CreaturePtr& creature = pair.second;
|
||||
const TilePtr& tile = creature->getCurrentTile();
|
||||
const TilePtr& tile = creature->getTile();
|
||||
if(tile) {
|
||||
tile->removeThing(creature);
|
||||
creature->setPosition(Position());
|
||||
|
@ -275,7 +275,7 @@ void Map::setCentralPosition(const Position& centralPosition)
|
|||
for(const auto& pair : m_knownCreatures) {
|
||||
const CreaturePtr& creature = pair.second;
|
||||
if(!isAwareOfPosition(creature->getPosition())) {
|
||||
const TilePtr& tile = creature->getCurrentTile();
|
||||
const TilePtr& tile = creature->getTile();
|
||||
if(tile) {
|
||||
tile->removeThing(creature);
|
||||
creature->setPosition(Position());
|
||||
|
|
|
@ -60,12 +60,14 @@ void MapView::draw(const Rect& rect)
|
|||
|
||||
int tileDrawFlags = 0;
|
||||
if(m_viewRange == NEAR_VIEW)
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems | Otc::DrawCreatures | Otc::DrawEffects;
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawCommonItems | Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawAnimations;
|
||||
else if(m_viewRange == MID_VIEW)
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems;
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawCommonItems;
|
||||
else if(m_viewRange == FAR_VIEW)
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls;
|
||||
else // HUGE_VIEW
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls;
|
||||
else if(m_tileSize >= 4) // HUGE_VIEW 1
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawGroundBorders;
|
||||
else // HUGE_VIEW 2
|
||||
tileDrawFlags = Otc::DrawGround;
|
||||
|
||||
bool animate = m_animated;
|
||||
|
@ -109,11 +111,11 @@ void MapView::draw(const Rect& rect)
|
|||
// avoid drawing texts on map in far zoom outs
|
||||
if(m_viewRange == NEAR_VIEW) {
|
||||
for(const CreaturePtr& creature : m_cachedFloorVisibleCreatures) {
|
||||
const TilePtr& tile = creature->getCurrentTile();
|
||||
const TilePtr& tile = creature->getTile();
|
||||
Position pos = tile->getPosition();
|
||||
|
||||
Point p = transformPositionTo2D(pos) - drawOffset;
|
||||
p += (creature->getWalkOffset()-tile->getDrawElevation() + Point(8, -8)) * scaleFactor;
|
||||
p += (creature->getWalkOffset()-tile->getDrawElevation() + Point(8, -10)) * scaleFactor;
|
||||
p.x = p.x * horizontalStretchFactor;
|
||||
p.y = p.y * verticalStretchFactor;
|
||||
p += rect.topLeft();
|
||||
|
|
|
@ -27,24 +27,18 @@
|
|||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
Missile::Missile() : Thing()
|
||||
{
|
||||
m_startTicks = 0;
|
||||
}
|
||||
|
||||
void Missile::draw(const Point& p, const Rect&)
|
||||
{
|
||||
if(m_id == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
float time = (g_clock.ticks() - m_startTicks) / m_duration;
|
||||
//internalDraw(p + Point(m_deltax * time, m_deltay * time), 0);
|
||||
}
|
||||
|
||||
void Missile::setPath(const Position& fromPosition, const Position& toPosition)
|
||||
{
|
||||
Otc::Direction direction = fromPosition.getDirectionFromPosition(toPosition);
|
||||
|
||||
int xPattern = 0, yPattern = 0;
|
||||
if(direction == Otc::NorthWest) {
|
||||
m_xPattern = 0;
|
||||
m_yPattern = 0;
|
||||
xPattern = 0;
|
||||
yPattern = 0;
|
||||
}
|
||||
else if(direction == Otc::North) {
|
||||
m_xPattern = 1;
|
||||
|
@ -79,20 +73,29 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition)
|
|||
m_yPattern = 1;
|
||||
}
|
||||
|
||||
//internalDraw(p + Point(m_deltax * time, m_deltay * time), 0, 0);
|
||||
*/
|
||||
}
|
||||
|
||||
void Missile::setPath(const Position& fromPosition, const Position& toPosition)
|
||||
{
|
||||
m_direction = fromPosition.getDirectionFromPosition(toPosition);
|
||||
|
||||
m_position = fromPosition;
|
||||
m_deltax = toPosition.x - fromPosition.x;
|
||||
m_deltay = toPosition.y - fromPosition.y;
|
||||
m_startTicks = g_clock.ticks();
|
||||
m_duration = 150 * std::sqrt(Point(m_deltax, m_deltay).length());
|
||||
m_deltax *= Otc::TILE_PIXELS;
|
||||
m_deltay *= Otc::TILE_PIXELS;
|
||||
m_animationTimer.restart();
|
||||
|
||||
// schedule removal
|
||||
auto self = asMissile();
|
||||
g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, m_duration);
|
||||
}
|
||||
|
||||
ThingType *Missile::getType()
|
||||
void Missile::setId(uint32 id)
|
||||
{
|
||||
return g_thingsType.getThingType(m_id, ThingsType::Missile);
|
||||
m_id = id;
|
||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Missile);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define SHOT_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include <framework/core/timer.h>
|
||||
#include "thing.h"
|
||||
|
||||
class Missile : public Thing
|
||||
|
@ -33,23 +34,24 @@ class Missile : public Thing
|
|||
};
|
||||
|
||||
public:
|
||||
Missile();
|
||||
|
||||
void draw(const Point& p, const Rect&);
|
||||
|
||||
void updateAnimation();
|
||||
|
||||
void setId(uint32 id);
|
||||
void setPath(const Position& fromPosition, const Position& toPosition);
|
||||
|
||||
ThingType *getType();
|
||||
uint32 getId() { return m_id; }
|
||||
|
||||
MissilePtr asMissile() { return std::static_pointer_cast<Missile>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
ticks_t m_startTicks;
|
||||
Timer m_animationTimer;
|
||||
int m_deltax;
|
||||
int m_deltay;
|
||||
float m_duration;
|
||||
uint16 m_id;
|
||||
Otc::Direction m_direction;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,20 +28,9 @@
|
|||
|
||||
Thing::Thing()
|
||||
{
|
||||
m_id = 0;
|
||||
m_xPattern = 0;
|
||||
m_yPattern = 0;
|
||||
m_zPattern = 0;
|
||||
m_animation = 0;
|
||||
m_type = g_thingsType.getEmptyThingType();
|
||||
}
|
||||
|
||||
void Thing::setId(uint32 id)
|
||||
{
|
||||
m_id = id;
|
||||
updateType();
|
||||
}
|
||||
|
||||
int Thing::getStackPriority()
|
||||
{
|
||||
if(isGround())
|
||||
|
@ -58,42 +47,28 @@ int Thing::getStackPriority()
|
|||
return 5;
|
||||
}
|
||||
|
||||
const TilePtr& Thing::getCurrentTile()
|
||||
const TilePtr& Thing::getTile()
|
||||
{
|
||||
return g_map.getTile(m_position);
|
||||
}
|
||||
|
||||
void Thing::internalDraw(const Point& dest, float scaleFactor, int layer)
|
||||
void Thing::internalDraw(const Point& dest, float scaleFactor, 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, m_xPattern, m_yPattern, m_zPattern, m_animation);
|
||||
int spriteId = getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animationPhase);
|
||||
if(!spriteId)
|
||||
continue;
|
||||
|
||||
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
|
||||
Rect drawRect((dest.x - w*scaledSize) - getDisplacementX()*scaleFactor,
|
||||
(dest.y - h*scaledSize) - getDisplacementY()*scaleFactor,
|
||||
Rect drawRect(dest.x - (w*Otc::TILE_PIXELS - getDisplacementX())*scaleFactor,
|
||||
dest.y - (h*Otc::TILE_PIXELS - getDisplacementY())*scaleFactor,
|
||||
scaledSize, scaledSize);
|
||||
|
||||
g_painter.setColor(Fw::white);
|
||||
g_painter.drawTexturedRect(drawRect, spriteTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Thing::updateType()
|
||||
{
|
||||
if(CreaturePtr creature = asCreature())
|
||||
m_type = g_thingsType.getThingType(creature->getOutfit().getId(), creature->getOutfit().getCategory());
|
||||
else if(asItem())
|
||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Item);
|
||||
else if(asMissile())
|
||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Missile);
|
||||
else if(asEffect())
|
||||
m_type = g_thingsType.getThingType(m_id, ThingsType::Effect);
|
||||
else
|
||||
m_type = g_thingsType.getEmptyThingType();
|
||||
}
|
||||
|
|
|
@ -40,19 +40,15 @@ public:
|
|||
virtual ~Thing() { }
|
||||
|
||||
virtual void startAnimation() { }
|
||||
virtual void draw(const Point& dest, float scaleFactor) { }
|
||||
virtual void draw(const Point& dest, float scaleFactor, bool animate) { }
|
||||
|
||||
virtual void setId(uint32 id);
|
||||
virtual void setPosition(const Position& position) { m_position = position; }
|
||||
virtual void setId(uint32 id) { }
|
||||
void setPosition(const Position& position) { m_position = position; }
|
||||
|
||||
uint32 getId() { return m_id; }
|
||||
virtual uint32 getId() { return 0; }
|
||||
Position getPosition() { return m_position; }
|
||||
int getStackPriority();
|
||||
const TilePtr& getCurrentTile();
|
||||
|
||||
void setXPattern(int xPattern) { m_xPattern = xPattern; }
|
||||
void setYPattern(int yPattern) { m_yPattern = yPattern; }
|
||||
void setZPattern(int zPattern) { m_zPattern = zPattern; }
|
||||
const TilePtr& getTile();
|
||||
|
||||
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
|
||||
virtual ItemPtr asItem() { return nullptr; }
|
||||
|
@ -105,14 +101,9 @@ public:
|
|||
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 layer);
|
||||
void updateType();
|
||||
void internalDraw(const Point& dest, float scaleFactor, int xPattern, int yPattern, int zPattern, int layer, int animationPhase);
|
||||
|
||||
uint32 m_id; //TODO: move to derived class to use less memory
|
||||
Position m_position;
|
||||
uint8 m_xPattern, m_yPattern, m_zPattern, m_animation; //TODO: remove this variables to use less memory
|
||||
|
||||
private:
|
||||
ThingType *m_type;
|
||||
};
|
||||
|
||||
|
|
|
@ -115,11 +115,12 @@ void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType)
|
|||
|
||||
ThingType *ThingsType::getThingType(uint16 id, Categories category)
|
||||
{
|
||||
assert(id != 0);
|
||||
if(category == Item)
|
||||
id -= 100;
|
||||
else if(category == Creature || category == Effect || category == Missile)
|
||||
id -= 1;
|
||||
assert(id < m_things[category].size());
|
||||
|
||||
if(id == 0 || id >= m_things[category].size())
|
||||
return &m_emptyThingType;
|
||||
return &m_things[category][id];
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ public:
|
|||
uint32 getSignature() { return m_signature; }
|
||||
bool isLoaded() { return m_loaded; }
|
||||
|
||||
int getFirstItemId() { return 100; }
|
||||
int getMaxItemid() { return m_things[Item].size() + 100 - 1; }
|
||||
uint16 getFirstItemId() { return 100; }
|
||||
uint16 getMaxItemid() { return m_things[Item].size() + 99; }
|
||||
|
||||
private:
|
||||
uint32 m_signature;
|
||||
|
|
|
@ -39,23 +39,18 @@ Tile::Tile(const Position& position)
|
|||
void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
|
||||
{
|
||||
int drawElevation = 0;
|
||||
|
||||
// optimization far far views
|
||||
if(drawFlags == Otc::DrawGround) {
|
||||
const ThingPtr& thing = m_things.front();
|
||||
if(thing)
|
||||
thing->draw(dest, scaleFactor);
|
||||
return;
|
||||
}
|
||||
bool animate = drawFlags & Otc::DrawAnimations;
|
||||
|
||||
// first bottom items
|
||||
if(drawFlags & Otc::DrawGround || drawFlags & Otc::DrawWalls) {
|
||||
if(drawFlags & Otc::DrawGround || drawFlags & Otc::DrawWalls || drawFlags & Otc::DrawGroundBorders) {
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
|
||||
break;
|
||||
|
||||
if((drawFlags & Otc::DrawGround && thing->isGround()) || (drawFlags & Otc::DrawWalls))
|
||||
thing->draw(dest - drawElevation*scaleFactor, scaleFactor);
|
||||
if((thing->isGround() && drawFlags & Otc::DrawGround) ||
|
||||
(thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) ||
|
||||
(thing->isOnBottom() && drawFlags & Otc::DrawWalls))
|
||||
thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate);
|
||||
|
||||
drawElevation += thing->getElevation();
|
||||
if(drawElevation > Otc::MAX_ELEVATION)
|
||||
|
@ -69,7 +64,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
|
|||
const ThingPtr& thing = *it;
|
||||
if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->asCreature())
|
||||
break;
|
||||
thing->draw(dest - drawElevation*scaleFactor, scaleFactor);
|
||||
thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate);
|
||||
|
||||
drawElevation += thing->getElevation();
|
||||
if(drawElevation > Otc::MAX_ELEVATION)
|
||||
|
@ -79,30 +74,32 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
|
|||
|
||||
// creatures
|
||||
if(drawFlags & Otc::DrawCreatures) {
|
||||
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);
|
||||
if(animate) {
|
||||
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, animate);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
|
||||
CreaturePtr creature = (*it)->asCreature();
|
||||
if(creature && !creature->isWalking())
|
||||
creature->draw(dest - drawElevation, scaleFactor);
|
||||
if(creature && (!creature->isWalking() || !animate))
|
||||
creature->draw(dest - drawElevation, scaleFactor, animate);
|
||||
}
|
||||
}
|
||||
|
||||
// effects
|
||||
if(drawFlags & Otc::DrawEffects) {
|
||||
for(const EffectPtr& effect : m_effects)
|
||||
effect->draw(dest, scaleFactor);
|
||||
effect->draw(dest, scaleFactor, animate);
|
||||
}
|
||||
|
||||
// top items
|
||||
if(drawFlags & Otc::DrawWalls) {
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(thing->isOnTop())
|
||||
thing->draw(dest - drawElevation, scaleFactor);
|
||||
thing->draw(dest - drawElevation, scaleFactor, animate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,9 +92,6 @@ void OTClient::registerLuaFunctions()
|
|||
g_lua.bindClassMemberFunction<Thing>("getPosition", &Thing::getPosition);
|
||||
g_lua.bindClassMemberFunction<Thing>("getStackPriority", &Thing::getStackPriority);
|
||||
g_lua.bindClassMemberFunction<Thing>("getAnimationPhases", &Thing::getAnimationPhases);
|
||||
g_lua.bindClassMemberFunction<Thing>("setXPattern", &Thing::setXPattern);
|
||||
g_lua.bindClassMemberFunction<Thing>("setYPattern", &Thing::setYPattern);
|
||||
g_lua.bindClassMemberFunction<Thing>("setZPattern", &Thing::setZPattern);
|
||||
g_lua.bindClassMemberFunction<Thing>("asThing", &Thing::asThing);
|
||||
g_lua.bindClassMemberFunction<Thing>("asItem", &Thing::asItem);
|
||||
g_lua.bindClassMemberFunction<Thing>("asCreature", &Thing::asCreature);
|
||||
|
|
|
@ -1125,7 +1125,7 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, int id)
|
|||
|
||||
ItemPtr item = Item::create(id);
|
||||
if(item->isStackable() || item->isFluidContainer() || item->isFluid())
|
||||
item->setCount(msg.getU8());
|
||||
item->setCountOrSubType(msg.getU8());
|
||||
|
||||
return item;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ void UICreature::draw()
|
|||
|
||||
if(m_creature) {
|
||||
g_painter.setColor(Fw::white);
|
||||
m_creature->draw(m_rect.bottomRight() - Point(32, 32) + Point(m_padding.left, m_padding.top), 1);
|
||||
m_creature->draw(m_rect.bottomRight() - Point(32, 32) + Point(m_padding.left, m_padding.top), 1, false);
|
||||
}
|
||||
|
||||
drawChildren();
|
||||
|
|
|
@ -38,7 +38,7 @@ void UIItem::draw()
|
|||
Point topLeft = m_rect.bottomRight() - Point(32, 32) + Point(m_padding.left, m_padding.top);
|
||||
|
||||
g_painter.setColor(Fw::white);
|
||||
m_item->draw(topLeft, 1);
|
||||
m_item->draw(topLeft, 1, true);
|
||||
|
||||
if(m_font && m_item->isStackable() && m_item->getCount() > 1) {
|
||||
std::string count = Fw::tostring(m_item->getCount());
|
||||
|
@ -65,12 +65,6 @@ void UIItem::setItemId(int id)
|
|||
}
|
||||
}
|
||||
|
||||
void UIItem::setItemCount(int count)
|
||||
{
|
||||
if(m_item)
|
||||
m_item->setCount(count);
|
||||
}
|
||||
|
||||
void UIItem::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
|
|
@ -34,13 +34,15 @@ public:
|
|||
void draw();
|
||||
|
||||
void setItemId(int id);
|
||||
void setItemCount(int count);
|
||||
void setItemCount(int count) { if(m_item) m_item->setCount(count); }
|
||||
void setItemSubType(int subType) { if(m_item) m_item->setSubType(subType); }
|
||||
void setItem(const ItemPtr& item) { m_item = item; }
|
||||
void setVirtual(bool virt) { m_virtual = virt; }
|
||||
void clearItem() { setItemId(0); }
|
||||
|
||||
int getItemId() { return m_item ? m_item->getId() : 0; }
|
||||
int getItemCount() { return m_item ? m_item->getCount() : 0; }
|
||||
int getItemSubType() { return m_item ? m_item->getSubType() : 0; }
|
||||
ItemPtr getItem() { return m_item; }
|
||||
bool isVirtual() { return m_virtual; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue