mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
Animated cursor for spell selection, removed hardcoded cursor ID's
This commit is contained in:
@ -38,13 +38,18 @@ void CCursorHandler::replaceBuffer(CIntObject * payload)
|
||||
updateBuffer(payload);
|
||||
}
|
||||
|
||||
void CCursorHandler::initCursor()
|
||||
CCursorHandler::CCursorHandler()
|
||||
: needUpdate(true)
|
||||
, buffer(nullptr)
|
||||
, cursorLayer(nullptr)
|
||||
, frameTime(0.f)
|
||||
, showing(false)
|
||||
{
|
||||
cursorLayer = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 40, 40);
|
||||
SDL_SetTextureBlendMode(cursorLayer, SDL_BLENDMODE_BLEND);
|
||||
|
||||
xpos = ypos = 0;
|
||||
type = ECursor::DEFAULT;
|
||||
type = Cursor::Type::DEFAULT;
|
||||
dndObject = nullptr;
|
||||
|
||||
cursors =
|
||||
@ -55,23 +60,28 @@ void CCursorHandler::initCursor()
|
||||
make_unique<CAnimImage>("CRSPELL", 0)
|
||||
};
|
||||
|
||||
currentCursor = cursors.at(int(ECursor::DEFAULT)).get();
|
||||
currentCursor = cursors.at(static_cast<size_t>(Cursor::Type::DEFAULT)).get();
|
||||
|
||||
buffer = CSDL_Ext::newSurface(40,40);
|
||||
|
||||
SDL_SetSurfaceBlendMode(buffer, SDL_BLENDMODE_NONE);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
changeGraphic(ECursor::ADVENTURE, 0);
|
||||
set(Cursor::Map::POINTER);
|
||||
}
|
||||
|
||||
void CCursorHandler::changeGraphic(ECursor::ECursorTypes type, int index)
|
||||
Point CCursorHandler::position() const
|
||||
{
|
||||
return Point(xpos, ypos);
|
||||
}
|
||||
|
||||
void CCursorHandler::changeGraphic(Cursor::Type type, size_t index)
|
||||
{
|
||||
if(type != this->type)
|
||||
{
|
||||
this->type = type;
|
||||
this->frame = index;
|
||||
currentCursor = cursors.at(int(type)).get();
|
||||
currentCursor = cursors.at(static_cast<size_t>(type)).get();
|
||||
currentCursor->setFrame(index);
|
||||
}
|
||||
else if(index != this->frame)
|
||||
@ -83,6 +93,27 @@ void CCursorHandler::changeGraphic(ECursor::ECursorTypes type, int index)
|
||||
replaceBuffer(currentCursor);
|
||||
}
|
||||
|
||||
void CCursorHandler::set(Cursor::Default index)
|
||||
{
|
||||
changeGraphic(Cursor::Type::DEFAULT, static_cast<size_t>(index));
|
||||
}
|
||||
|
||||
void CCursorHandler::set(Cursor::Map index)
|
||||
{
|
||||
changeGraphic(Cursor::Type::ADVENTURE, static_cast<size_t>(index));
|
||||
}
|
||||
|
||||
void CCursorHandler::set(Cursor::Combat index)
|
||||
{
|
||||
changeGraphic(Cursor::Type::COMBAT, static_cast<size_t>(index));
|
||||
}
|
||||
|
||||
void CCursorHandler::set(Cursor::Spellcast index)
|
||||
{
|
||||
//Note: this is animated cursor, ignore specified frame and only change type
|
||||
changeGraphic(Cursor::Type::SPELLBOOK, frame);
|
||||
}
|
||||
|
||||
void CCursorHandler::dragAndDropCursor(std::unique_ptr<CAnimImage> object)
|
||||
{
|
||||
dndObject = std::move(object);
|
||||
@ -100,54 +131,57 @@ void CCursorHandler::cursorMove(const int & x, const int & y)
|
||||
|
||||
void CCursorHandler::shiftPos( int &x, int &y )
|
||||
{
|
||||
if(( type == ECursor::COMBAT && frame != ECursor::COMBAT_POINTER) || type == ECursor::SPELLBOOK)
|
||||
if(( type == Cursor::Type::COMBAT && frame != static_cast<size_t>(Cursor::Combat::POINTER)) || type == Cursor::Type::SPELLBOOK)
|
||||
{
|
||||
x-=16;
|
||||
y-=16;
|
||||
|
||||
// Properly align the melee attack cursors.
|
||||
if (type == ECursor::COMBAT)
|
||||
if (type == Cursor::Type::COMBAT)
|
||||
{
|
||||
switch (frame)
|
||||
switch (static_cast<Cursor::Combat>(frame))
|
||||
{
|
||||
case 7: // Bottom left
|
||||
case Cursor::Combat::HIT_NORTHEAST:
|
||||
x -= 6;
|
||||
y += 16;
|
||||
break;
|
||||
case 8: // Left
|
||||
case Cursor::Combat::HIT_EAST:
|
||||
x -= 16;
|
||||
y += 10;
|
||||
break;
|
||||
case 9: // Top left
|
||||
case Cursor::Combat::HIT_SOUTHEAST:
|
||||
x -= 6;
|
||||
y -= 6;
|
||||
break;
|
||||
case 10: // Top right
|
||||
case Cursor::Combat::HIT_SOUTHWEST:
|
||||
x += 16;
|
||||
y -= 6;
|
||||
break;
|
||||
case 11: // Right
|
||||
case Cursor::Combat::HIT_WEST:
|
||||
x += 16;
|
||||
y += 11;
|
||||
break;
|
||||
case 12: // Bottom right
|
||||
case Cursor::Combat::HIT_NORTHWEST:
|
||||
x += 16;
|
||||
y += 16;
|
||||
break;
|
||||
case 13: // Below
|
||||
case Cursor::Combat::HIT_NORTH:
|
||||
x += 9;
|
||||
y += 16;
|
||||
break;
|
||||
case 14: // Above
|
||||
case Cursor::Combat::HIT_SOUTH:
|
||||
x += 9;
|
||||
y -= 15;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type == ECursor::ADVENTURE)
|
||||
else if(type == Cursor::Type::ADVENTURE)
|
||||
{
|
||||
if (frame == 0); //to exclude
|
||||
if (frame == 0)
|
||||
{
|
||||
//no-op
|
||||
}
|
||||
else if(frame == 2)
|
||||
{
|
||||
x -= 12;
|
||||
@ -219,6 +253,27 @@ void CCursorHandler::render()
|
||||
if(!showing)
|
||||
return;
|
||||
|
||||
if (type == Cursor::Type::SPELLBOOK)
|
||||
{
|
||||
static const float frameDisplayDuration = 0.1f;
|
||||
|
||||
frameTime += GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
||||
size_t newFrame = frame;
|
||||
|
||||
while (frameTime > frameDisplayDuration)
|
||||
{
|
||||
frameTime -= frameDisplayDuration;
|
||||
newFrame++;
|
||||
}
|
||||
|
||||
auto & animation = cursors.at(static_cast<size_t>(type));
|
||||
|
||||
while (newFrame > animation->size())
|
||||
newFrame -= animation->size();
|
||||
|
||||
changeGraphic(Cursor::Type::SPELLBOOK, newFrame);
|
||||
}
|
||||
|
||||
//the must update texture in the main (renderer) thread, but changes to cursor type may come from other threads
|
||||
updateTexture();
|
||||
|
||||
@ -250,15 +305,6 @@ void CCursorHandler::updateTexture()
|
||||
}
|
||||
}
|
||||
|
||||
CCursorHandler::CCursorHandler()
|
||||
: needUpdate(true),
|
||||
buffer(nullptr),
|
||||
cursorLayer(nullptr),
|
||||
showing(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CCursorHandler::~CCursorHandler()
|
||||
{
|
||||
if(buffer)
|
||||
|
Reference in New Issue
Block a user