mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
A patch from Gernsworth related to #1204 — spell effects will be layered along with the creatures.
This commit is contained in:
parent
4ac2a6e8b6
commit
d4ce091d2b
@ -772,12 +772,12 @@ void CShootingAnimation::endAnim()
|
||||
delete this;
|
||||
}
|
||||
|
||||
CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, ui32 _effect, BattleHex _destTile, int _dx, int _dy, bool _Vflip)
|
||||
:CBattleAnimation(_owner), effect(_effect), destTile(_destTile), customAnim(""), x(0), y(0), dx(_dx), dy(_dy), Vflip(_Vflip)
|
||||
CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, ui32 _effect, BattleHex _destTile, int _dx, int _dy, bool _Vflip, bool _areaEffect)
|
||||
:CBattleAnimation(_owner), effect(_effect), destTile(_destTile), customAnim(""), x(0), y(0), dx(_dx), dy(_dy), Vflip(_Vflip) , areaEffect(_areaEffect)
|
||||
{}
|
||||
|
||||
CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, std::string _customAnim, int _x, int _y, int _dx, int _dy, bool _Vflip)
|
||||
:CBattleAnimation(_owner), effect(-1), destTile(0), customAnim(_customAnim), x(_x), y(_y), dx(_dx), dy(_dy), Vflip(_Vflip)
|
||||
CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, std::string _customAnim, int _x, int _y, int _dx, int _dy, bool _Vflip, bool _areaEffect)
|
||||
:CBattleAnimation(_owner), effect(-1), destTile(0), customAnim(_customAnim), x(_x), y(_y), dx(_dx), dy(_dy), Vflip(_Vflip), areaEffect(_areaEffect)
|
||||
{}
|
||||
|
||||
bool CSpellEffectAnimation::init()
|
||||
@ -821,6 +821,7 @@ bool CSpellEffectAnimation::init()
|
||||
be.maxFrame = be.anim->ourImages.size();
|
||||
be.x = i * anim->width + owner->pos.x;
|
||||
be.y = j * anim->height + owner->pos.y;
|
||||
be.position = BattleHex::INVALID;
|
||||
|
||||
owner->battleEffects.push_back(be);
|
||||
}
|
||||
@ -866,6 +867,7 @@ bool CSpellEffectAnimation::init()
|
||||
break;
|
||||
case 0: // Prayer and Lightning Bolt.
|
||||
case 1:
|
||||
case 19: // Slow
|
||||
// Position effect with it's bottom center touching the bottom center of affected tile(s).
|
||||
be.x = tilePos.x + tilePos.w/2 - be.anim->width/2;
|
||||
be.y = tilePos.y + tilePos.h - be.anim->height;
|
||||
@ -882,6 +884,12 @@ bool CSpellEffectAnimation::init()
|
||||
if (destStack != nullptr && destStack->doubleWide())
|
||||
be.x += (destStack->attackerOwned ? -1 : 1)*tilePos.w/2;
|
||||
|
||||
//Indicate if effect should be drawn on top of everything or just on top of the hex
|
||||
if(areaEffect)
|
||||
be.position = BattleHex::INVALID;
|
||||
else
|
||||
be.position = destTile;
|
||||
|
||||
owner->battleEffects.push_back(be);
|
||||
}
|
||||
else //there is nothing to play
|
||||
|
@ -217,12 +217,13 @@ private:
|
||||
std::string customAnim;
|
||||
int x, y, dx, dy;
|
||||
bool Vflip;
|
||||
bool areaEffect;
|
||||
public:
|
||||
bool init();
|
||||
void nextFrame();
|
||||
void endAnim();
|
||||
|
||||
CSpellEffectAnimation(CBattleInterface * _owner, ui32 _effect, BattleHex _destTile, int _dx = 0, int _dy = 0, bool _Vflip = false);
|
||||
CSpellEffectAnimation(CBattleInterface * _owner, std::string _customAnim, int _x, int _y, int _dx = 0, int _dy = 0, bool _Vflip = false);
|
||||
CSpellEffectAnimation(CBattleInterface * _owner, ui32 _effect, BattleHex _destTile, int _dx = 0, int _dy = 0, bool _Vflip = false, bool _areaEffect = true);
|
||||
CSpellEffectAnimation(CBattleInterface * _owner, std::string _customAnim, int _x, int _y, int _dx = 0, int _dy = 0, bool _Vflip = false, bool _areaEffect = true);
|
||||
virtual ~CSpellEffectAnimation(){};
|
||||
};
|
||||
|
@ -798,6 +798,18 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
}
|
||||
}
|
||||
|
||||
//Get all the spell effects that need to be drawn with the stack
|
||||
std::vector<const BattleEffect *> battleEffectByHex[GameConstants::BFIELD_SIZE];
|
||||
std::vector<const BattleEffect *> topBattleEffects;
|
||||
for (auto & battleEffect : battleEffects)
|
||||
{
|
||||
const BattleEffect *e = &battleEffect;
|
||||
if(e->position.isValid())
|
||||
battleEffectByHex[e->position].push_back(e);
|
||||
else
|
||||
topBattleEffects.push_back(e);
|
||||
}
|
||||
|
||||
for(auto & elem : stackDeadByHex) //showing dead stacks
|
||||
{
|
||||
for(size_t v=0; v<elem.size(); ++v)
|
||||
@ -809,10 +821,11 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
std::vector<const CStack *> flyingStacks; //flying stacks should be displayed later, over other stacks and obstacles
|
||||
if (!siegeH)
|
||||
{
|
||||
for(int b = 0; b < GameConstants::BFIELD_SIZE; ++b) //showing alive stacks
|
||||
for(int b = 0; b < GameConstants::BFIELD_SIZE; ++b) //showing alive stacks and spells
|
||||
{
|
||||
showObstacles(&hexToObstacle, obstacles, b, to);
|
||||
showAliveStacks(stackAliveByHex, b, &flyingStacks, to);
|
||||
showBattleEffects(battleEffectByHex[b], to);
|
||||
}
|
||||
}
|
||||
// Siege drawing
|
||||
@ -882,6 +895,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
int hex = j * 17 + k;
|
||||
showObstacles(&hexToObstacle, obstacles, hex, to);
|
||||
showAliveStacks(stackAliveByHex, hex, &flyingStacks, to);
|
||||
showBattleEffects(battleEffectByHex[hex], to);
|
||||
showPieceOfWall(to, hex, stacks);
|
||||
}
|
||||
|
||||
@ -899,15 +913,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
projectileShowHelper(to);
|
||||
|
||||
//showing spell effects
|
||||
if(battleEffects.size())
|
||||
{
|
||||
for(auto & elem : battleEffects)
|
||||
{
|
||||
SDL_Surface * bitmapToBlit = elem.anim->ourImages[(elem.frame)%elem.anim->ourImages.size()].bitmap;
|
||||
SDL_Rect temp_rect = genRect(bitmapToBlit->h, bitmapToBlit->w, elem.x, elem.y);
|
||||
SDL_BlitSurface(bitmapToBlit, nullptr, to, &temp_rect);
|
||||
}
|
||||
}
|
||||
showBattleEffects(topBattleEffects, to);
|
||||
|
||||
SDL_SetClipRect(to, &buf); //restoring previous clip_rect
|
||||
|
||||
@ -997,6 +1003,16 @@ void CBattleInterface::showObstacles(std::multimap<BattleHex, int> *hexToObstacl
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::showBattleEffects(const std::vector<const BattleEffect *> &battleEffects, SDL_Surface *to)
|
||||
{
|
||||
for(auto & elem : battleEffects)
|
||||
{
|
||||
SDL_Surface * bitmapToBlit = elem->anim->ourImages[(elem->frame)%elem->anim->ourImages.size()].bitmap;
|
||||
SDL_Rect temp_rect = genRect(bitmapToBlit->h, bitmapToBlit->w, elem->x, elem->y);
|
||||
SDL_BlitSurface(bitmapToBlit, nullptr, to, &temp_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
if(key.keysym.sym == SDLK_q && key.state == SDL_PRESSED)
|
||||
@ -1924,7 +1940,8 @@ void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
|
||||
{
|
||||
for(auto & elem : sse.stacks)
|
||||
{
|
||||
displayEffect(CGI->spellh->spells[effID]->mainEffectAnim, curInt->cb->battleGetStackByID(elem)->position);
|
||||
bool areaEffect(CGI->spellh->spells[effID]->getTargetType() == CSpell::ETargetType::NO_TARGET);
|
||||
displayEffect(CGI->spellh->spells[effID]->mainEffectAnim, curInt->cb->battleGetStackByID(elem)->position, areaEffect);
|
||||
}
|
||||
}
|
||||
else if (sse.stacks.size() == 1 && sse.effect.size() == 2)
|
||||
@ -2015,9 +2032,9 @@ void CBattleInterface::castThisSpell(int spellID)
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::displayEffect(ui32 effect, int destTile)
|
||||
void CBattleInterface::displayEffect(ui32 effect, int destTile, bool areaEffect)
|
||||
{
|
||||
addNewAnim(new CSpellEffectAnimation(this, effect, destTile));
|
||||
addNewAnim(new CSpellEffectAnimation(this, effect, destTile, 0, 0, false, areaEffect));
|
||||
}
|
||||
|
||||
void CBattleInterface::battleTriggerEffect(const BattleTriggerEffect & bte)
|
||||
|
@ -70,6 +70,7 @@ struct BattleEffect
|
||||
int frame, maxFrame;
|
||||
CDefHandler * anim; //animation to display
|
||||
int effectID; //uniqueID equal ot ID of appropriate CSpellEffectAnim
|
||||
BattleHex position; //Indicates if effect which hex the effect is drawn on
|
||||
};
|
||||
|
||||
/// Small struct which is needed for drawing the parabolic trajectory of the catapult cannon
|
||||
@ -158,6 +159,7 @@ private:
|
||||
void showAliveStacks(std::vector<const CStack *> *aliveStacks, int hex, std::vector<const CStack *> *flyingStacks, SDL_Surface *to); // loops through all stacks at a given hex position
|
||||
void showPieceOfWall(SDL_Surface * to, int hex, const std::vector<const CStack*> & stacks); //helper function for show
|
||||
void showObstacles(std::multimap<BattleHex, int> *hexToObstacle, std::vector<shared_ptr<const CObstacleInstance> > &obstacles, int hex, SDL_Surface *to); // show all obstacles at a given hex position
|
||||
void showBattleEffects(const std::vector<const BattleEffect *> &battleEffects, SDL_Surface *to); //Show all spells in the given vector
|
||||
SDL_Surface *imageOfObstacle(const CObstacleInstance &oi) const;
|
||||
Point whereToBlitObstacleImage(SDL_Surface *image, const CObstacleInstance &obstacle) const;
|
||||
void redrawBackgroundWithHexes(const CStack * activeStack);
|
||||
@ -263,7 +265,7 @@ public:
|
||||
void spellCast(const BattleSpellCast * sc); //called when a hero casts a spell
|
||||
void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
|
||||
void castThisSpell(int spellID); //called when player has chosen a spell from spellbook
|
||||
void displayEffect(ui32 effect, int destTile); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
|
||||
void displayEffect(ui32 effect, int destTile, bool areaEffect = true); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
|
||||
void battleTriggerEffect(const BattleTriggerEffect & bte);
|
||||
void setBattleCursor(const int myNumber); //really complex and messy, sets attackingHex
|
||||
void endAction(const BattleAction* action);
|
||||
|
Loading…
Reference in New Issue
Block a user