animated text
This commit is contained in:
parent
37a6a38ca6
commit
5830a3dc3e
|
@ -61,6 +61,16 @@ public:
|
||||||
bool operator==(const Color& other) const { return other.m_rgba == m_rgba; }
|
bool operator==(const Color& other) const { return other.m_rgba == m_rgba; }
|
||||||
bool operator!=(const Color& other) const { return other.m_rgba != m_rgba; }
|
bool operator!=(const Color& other) const { return other.m_rgba != m_rgba; }
|
||||||
|
|
||||||
|
static Color from8bit(int color) {
|
||||||
|
if(color >= 216 || color <= 0)
|
||||||
|
return Color(0, 0, 0);
|
||||||
|
|
||||||
|
int r = int(color / 36) % 6 * 51;
|
||||||
|
int g = int(color / 6) % 6 * 51;
|
||||||
|
int b = color % 6 * 51;
|
||||||
|
return Color(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
uint32 m_rgba;
|
uint32 m_rgba;
|
||||||
|
|
|
@ -29,6 +29,7 @@ SET(otclient_SOURCES ${otclient_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/missile.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/missile.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/localplayer.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/localplayer.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/outfit.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/outfit.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/animatedtext.cpp
|
||||||
|
|
||||||
# otclient ui
|
# otclient ui
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/uiitem.cpp
|
${CMAKE_CURRENT_LIST_DIR}/ui/uiitem.cpp
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "animatedtext.h"
|
||||||
|
#include "outfit.h"
|
||||||
|
#include "map.h"
|
||||||
|
#include <framework/core/clock.h>
|
||||||
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
|
||||||
|
AnimatedText::AnimatedText()
|
||||||
|
{
|
||||||
|
m_font = g_fonts.getFont("verdana-11px-rounded");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedText::start()
|
||||||
|
{
|
||||||
|
m_startTime = g_clock.time();
|
||||||
|
|
||||||
|
auto self = asAnimatedText();
|
||||||
|
|
||||||
|
// schedule removal
|
||||||
|
g_dispatcher.scheduleEvent([self]() {
|
||||||
|
g_map.removeThing(self);
|
||||||
|
}, DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedText::draw(const Point& p)
|
||||||
|
{
|
||||||
|
assert(m_font);
|
||||||
|
m_font->renderText(m_text, Rect(p + Point(0, -20.0 * g_clock.timeElapsed(m_startTime) / (DURATION / 1000)), m_textSize), Fw::AlignTopCenter, m_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedText::setColor(int color)
|
||||||
|
{
|
||||||
|
m_color = Color::from8bit(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedText::setText(const std::string& text)
|
||||||
|
{
|
||||||
|
m_textSize = m_font->calculateTextRectSize(text);
|
||||||
|
m_text = text;
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANIMATEDTEXT_H
|
||||||
|
#define ANIMATEDTEXT_H
|
||||||
|
|
||||||
|
#include "thing.h"
|
||||||
|
#include <framework/graphics/fontmanager.h>
|
||||||
|
|
||||||
|
class AnimatedText : public Thing
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
DURATION = 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
AnimatedText();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void draw(const Point& p);
|
||||||
|
|
||||||
|
void setColor(int color);
|
||||||
|
void setText(const std::string& text);
|
||||||
|
|
||||||
|
AnimatedTextPtr asAnimatedText() { return std::static_pointer_cast<AnimatedText>(shared_from_this()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FontPtr m_font;
|
||||||
|
Size m_textSize;
|
||||||
|
std::string m_text;
|
||||||
|
Color m_color;
|
||||||
|
double m_startTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -33,6 +33,7 @@ class Effect;
|
||||||
class Missile;
|
class Missile;
|
||||||
class Player;
|
class Player;
|
||||||
class LocalPlayer;
|
class LocalPlayer;
|
||||||
|
class AnimatedText;
|
||||||
|
|
||||||
typedef std::shared_ptr<Tile> TilePtr;
|
typedef std::shared_ptr<Tile> TilePtr;
|
||||||
typedef std::shared_ptr<Thing> ThingPtr;
|
typedef std::shared_ptr<Thing> ThingPtr;
|
||||||
|
@ -42,6 +43,7 @@ typedef std::shared_ptr<Effect> EffectPtr;
|
||||||
typedef std::shared_ptr<Missile> MissilePtr;
|
typedef std::shared_ptr<Missile> MissilePtr;
|
||||||
typedef std::shared_ptr<Player> PlayerPtr;
|
typedef std::shared_ptr<Player> PlayerPtr;
|
||||||
typedef std::shared_ptr<LocalPlayer> LocalPlayerPtr;
|
typedef std::shared_ptr<LocalPlayer> LocalPlayerPtr;
|
||||||
|
typedef std::shared_ptr<AnimatedText> AnimatedTextPtr;
|
||||||
|
|
||||||
typedef std::vector<ThingPtr> ThingList;
|
typedef std::vector<ThingPtr> ThingList;
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,14 @@ void Map::draw(const Rect& rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw animated text
|
||||||
|
for(auto it = m_animatedTexts.begin(), end = m_animatedTexts.end(); it != end; ++it) {
|
||||||
|
Point pos = positionTo2D((*it)->getPosition()) - m_drawOffset;
|
||||||
|
pos.x *= horizontalStretchFactor;
|
||||||
|
pos.y *= verticalStretchFactor;
|
||||||
|
(*it)->draw(rect.topLeft() + pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::clean()
|
void Map::clean()
|
||||||
|
@ -225,6 +233,11 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
|
||||||
m_missilesAtFloor[shot->getPosition().z].push_back(shot);
|
m_missilesAtFloor[shot->getPosition().z].push_back(shot);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) {
|
||||||
|
animatedText->start();
|
||||||
|
m_animatedTexts.push_back(animatedText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TilePtr tile = getTile(pos);
|
TilePtr tile = getTile(pos);
|
||||||
tile->addThing(thing, stackPos);
|
tile->addThing(thing, stackPos);
|
||||||
|
@ -258,6 +271,12 @@ void Map::removeThing(const ThingPtr& thing)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) {
|
||||||
|
auto it = std::find(m_animatedTexts.begin(), m_animatedTexts.end(), animatedText);
|
||||||
|
if(it != m_animatedTexts.end())
|
||||||
|
m_animatedTexts.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(TilePtr& tile = m_tiles[thing->getPosition()])
|
if(TilePtr& tile = m_tiles[thing->getPosition()])
|
||||||
tile->removeThing(thing);
|
tile->removeThing(thing);
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#define MAP_H
|
#define MAP_H
|
||||||
|
|
||||||
#include "creature.h"
|
#include "creature.h"
|
||||||
|
#include "animatedtext.h"
|
||||||
|
#include <framework/core/clock.h>
|
||||||
#include <framework/graphics/declarations.h>
|
#include <framework/graphics/declarations.h>
|
||||||
|
|
||||||
class Map
|
class Map
|
||||||
|
@ -76,6 +78,7 @@ private:
|
||||||
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
|
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
|
||||||
std::map<uint32, CreaturePtr> m_creatures;
|
std::map<uint32, CreaturePtr> m_creatures;
|
||||||
std::array<std::vector<MissilePtr>, MAX_Z> m_missilesAtFloor;
|
std::array<std::vector<MissilePtr>, MAX_Z> m_missilesAtFloor;
|
||||||
|
std::vector<AnimatedTextPtr> m_animatedTexts;
|
||||||
|
|
||||||
Light m_light;
|
Light m_light;
|
||||||
Position m_centralPosition;
|
Position m_centralPosition;
|
||||||
|
|
|
@ -81,3 +81,7 @@ int Thing::getStackPriority()
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThingType *Thing::getType()
|
||||||
|
{
|
||||||
|
return g_thingsType.getEmptyThingType();
|
||||||
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
uint32 getId() const { return m_id; }
|
uint32 getId() const { return m_id; }
|
||||||
Position getPosition() const { return m_position; }
|
Position getPosition() const { return m_position; }
|
||||||
int getStackPriority();
|
int getStackPriority();
|
||||||
virtual ThingType *getType() = 0;
|
virtual ThingType *getType();
|
||||||
int getAnimationPhases() { return m_type->dimensions[ThingType::AnimationPhases]; }
|
int getAnimationPhases() { return m_type->dimensions[ThingType::AnimationPhases]; }
|
||||||
|
|
||||||
void setXPattern(int xPattern) { m_xPattern = xPattern; }
|
void setXPattern(int xPattern) { m_xPattern = xPattern; }
|
||||||
|
@ -61,6 +61,7 @@ public:
|
||||||
virtual MissilePtr asMissile() { return nullptr; }
|
virtual MissilePtr asMissile() { return nullptr; }
|
||||||
virtual PlayerPtr asPlayer() { return nullptr; }
|
virtual PlayerPtr asPlayer() { return nullptr; }
|
||||||
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
|
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
|
||||||
|
virtual AnimatedTextPtr asAnimatedText() { return nullptr; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void internalDraw(const Point& p, int layers);
|
void internalDraw(const Point& p, int layers);
|
||||||
|
|
|
@ -537,9 +537,16 @@ void ProtocolGame::parseMagicEffect(InputMessage& msg)
|
||||||
|
|
||||||
void ProtocolGame::parseAnimatedText(InputMessage& msg)
|
void ProtocolGame::parseAnimatedText(InputMessage& msg)
|
||||||
{
|
{
|
||||||
parsePosition(msg); // textPos
|
Position position = parsePosition(msg);
|
||||||
msg.getU8(); // color
|
uint8 color = msg.getU8();
|
||||||
msg.getString(); // text
|
std::string text = msg.getString();
|
||||||
|
|
||||||
|
AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText);
|
||||||
|
animatedText->setPosition(position);
|
||||||
|
animatedText->setColor(color);
|
||||||
|
animatedText->setText(text);
|
||||||
|
|
||||||
|
g_map.addThing(animatedText, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseDistanceMissile(InputMessage& msg)
|
void ProtocolGame::parseDistanceMissile(InputMessage& msg)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <otclient/core/tile.h>
|
#include <otclient/core/tile.h>
|
||||||
#include <otclient/core/missile.h>
|
#include <otclient/core/missile.h>
|
||||||
#include <otclient/core/effect.h>
|
#include <otclient/core/effect.h>
|
||||||
|
#include <otclient/core/animatedtext.h>
|
||||||
|
|
||||||
UIMap::UIMap()
|
UIMap::UIMap()
|
||||||
{
|
{
|
||||||
|
@ -72,10 +73,17 @@ bool UIMap::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
||||||
|
|
||||||
// cool testing \/
|
// cool testing \/
|
||||||
if(button == Fw::MouseLeftButton) {
|
if(button == Fw::MouseLeftButton) {
|
||||||
MissilePtr shot = MissilePtr(new Missile());
|
/*MissilePtr shot = MissilePtr(new Missile());
|
||||||
shot->setId(1);
|
shot->setId(1);
|
||||||
shot->setPath(g_map.getCentralPosition(), tilePos);
|
shot->setPath(g_map.getCentralPosition(), tilePos);
|
||||||
g_map.addThing(shot, g_map.getCentralPosition());
|
g_map.addThing(shot, g_map.getCentralPosition());*/
|
||||||
|
|
||||||
|
AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText);
|
||||||
|
animatedText->setPosition(g_map.getCentralPosition());
|
||||||
|
animatedText->setColor(12);
|
||||||
|
animatedText->setText("text");
|
||||||
|
|
||||||
|
g_map.addThing(animatedText, g_map.getCentralPosition());
|
||||||
}
|
}
|
||||||
else if(button == Fw::MouseRightButton) {
|
else if(button == Fw::MouseRightButton) {
|
||||||
EffectPtr effect = EffectPtr(new Effect());
|
EffectPtr effect = EffectPtr(new Effect());
|
||||||
|
|
Loading…
Reference in New Issue