mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Bugfixing: fix crashes on battle start & most noticeable glitches
This commit is contained in:
parent
0cae259f53
commit
e76cd1b6a7
@ -161,7 +161,26 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
|
||||
// 1) Vampire mansion in Necropolis (not 1st color is transparent)
|
||||
// 2) Battle background when fighting on grass/dirt, topmost sky part (NO transparent color)
|
||||
// 3) New objects that may use 24-bit images for icons (e.g. witchking arts)
|
||||
if (ret->format->palette)
|
||||
// 4) special case - there are 2 .bmp images that have semi-transparency (CCELLGRD.BMP & CCELLSHD.BMP)
|
||||
if (ret->format->palette &&
|
||||
ret->format->palette->colors[0].r == 255 &&
|
||||
ret->format->palette->colors[0].g == 0 &&
|
||||
ret->format->palette->colors[0].b == 255 )
|
||||
{
|
||||
static SDL_Color shadow[3] =
|
||||
{
|
||||
{ 0, 0, 0, 0},// 100% - transparency
|
||||
{ 0, 0, 0, 32},// 75% - shadow border,
|
||||
{ 0, 0, 0, 128},// 50% - shadow body
|
||||
};
|
||||
|
||||
CSDL_Ext::setColorKey(ret, ret->format->palette->colors[0]);
|
||||
|
||||
ret->format->palette->colors[0] = shadow[0];
|
||||
ret->format->palette->colors[1] = shadow[1];
|
||||
ret->format->palette->colors[4] = shadow[2];
|
||||
}
|
||||
else if (ret->format->palette)
|
||||
{
|
||||
CSDL_Ext::setDefaultColorKeyPresize(ret);
|
||||
}
|
||||
@ -173,6 +192,7 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
|
||||
{
|
||||
CSDL_Ext::setDefaultColorKey(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "../gui/CAnimation.h"
|
||||
#include "../gui/CCursorHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CStack.h"
|
||||
@ -488,8 +487,8 @@ bool CMovementAnimation::init()
|
||||
owner->moveSoundHander = CCS->soundh->playSound(battle_sound(stack->getCreature(), move), -1);
|
||||
}
|
||||
|
||||
Point begPosition = CClickableHex::getXYUnitAnim(oldPos, stack, owner);
|
||||
Point endPosition = CClickableHex::getXYUnitAnim(nextHex, stack, owner);
|
||||
Point begPosition = owner->stacksController->getStackPositionAtHex(oldPos, stack);
|
||||
Point endPosition = owner->stacksController->getStackPositionAtHex(nextHex, stack);
|
||||
|
||||
timeToMove = AnimationControls::getMovementDuration(stack->getCreature());
|
||||
|
||||
@ -522,7 +521,7 @@ void CMovementAnimation::nextFrame()
|
||||
if(progress >= 1.0)
|
||||
{
|
||||
// Sets the position of the creature animation sprites
|
||||
Point coords = CClickableHex::getXYUnitAnim(nextHex, stack, owner);
|
||||
Point coords = owner->stacksController->getStackPositionAtHex(nextHex, stack);
|
||||
myAnim->pos = coords;
|
||||
|
||||
// true if creature haven't reached the final destination hex
|
||||
@ -552,7 +551,7 @@ void CMovementAnimation::endAnim()
|
||||
{
|
||||
assert(stack);
|
||||
|
||||
myAnim->pos = CClickableHex::getXYUnitAnim(nextHex, stack, owner);
|
||||
myAnim->pos = owner->stacksController->getStackPositionAtHex(nextHex, stack);
|
||||
CBattleAnimation::endAnim();
|
||||
|
||||
owner->stacksController->addNewAnim(new CMovementEndAnimation(owner, stack, nextHex));
|
||||
@ -692,7 +691,7 @@ void CBattleStackAnimation::rotateStack(BattleHex hex)
|
||||
{
|
||||
setStackFacingRight(stack, !stackFacingRight(stack));
|
||||
|
||||
stackAnimation(stack)->pos = CClickableHex::getXYUnitAnim(hex, stack, owner);
|
||||
stackAnimation(stack)->pos = owner->stacksController->getStackPositionAtHex(hex, stack);
|
||||
}
|
||||
|
||||
void CReverseAnimation::setupSecondPart()
|
||||
@ -761,7 +760,7 @@ bool CShootingAnimation::init()
|
||||
void CShootingAnimation::setAnimationGroup()
|
||||
{
|
||||
Point shooterPos = stackAnimation(attackingStack)->pos.topLeft();
|
||||
Point shotTarget = CClickableHex::getXYUnitAnim(dest, attackedStack, owner) + Point(225, 225);
|
||||
Point shotTarget = owner->stacksController->getStackPositionAtHex(dest, attackedStack) + Point(225, 225);
|
||||
|
||||
//maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
|
||||
static const double straightAngle = 0.2;
|
||||
@ -784,7 +783,7 @@ void CShootingAnimation::initializeProjectile()
|
||||
if(shooterInfo->idNumber == CreatureID::ARROW_TOWERS)
|
||||
shooterInfo = owner->siegeController->getTurretCreature();
|
||||
|
||||
Point shotTarget = CClickableHex::getXYUnitAnim(dest, attackedStack, owner) + Point(225, 225);
|
||||
Point shotTarget = owner->stacksController->getStackPositionAtHex(dest, attackedStack) + Point(225, 225);
|
||||
Point shotOrigin = stackAnimation(attackingStack)->pos.topLeft() + Point(222, 265);
|
||||
int multiplier = stackFacingRight(attackingStack) ? 1 : -1;
|
||||
|
||||
@ -922,9 +921,9 @@ bool CCastAnimation::init()
|
||||
|
||||
// NOTE: two lines below return different positions (very notable with 2-hex creatures). Obtaining via creanims seems to be more precise
|
||||
fromPos = stackAnimation(attackingStack)->pos.topLeft();
|
||||
//xycoord = CClickableHex::getXYUnitAnim(shooter->getPosition(), true, shooter, owner);
|
||||
//xycoord = owner->stacksController->getStackPositionAtHex(shooter->getPosition(), shooter);
|
||||
|
||||
destPos = CClickableHex::getXYUnitAnim(dest, attackedStack, owner);
|
||||
destPos = owner->stacksController->getStackPositionAtHex(dest, attackedStack);
|
||||
|
||||
|
||||
double projectileAngle = atan2(fabs((double)destPos.y - fromPos.y), fabs((double)destPos.x - fromPos.x));
|
||||
|
@ -26,10 +26,11 @@
|
||||
#include "../../lib/CStack.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
|
||||
CBattleControlPanel::CBattleControlPanel(CBattleInterface * owner):
|
||||
CBattleControlPanel::CBattleControlPanel(CBattleInterface * owner, const Point & position):
|
||||
owner(owner)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
pos += position;
|
||||
|
||||
//preparing buttons and console
|
||||
bOptions = std::make_shared<CButton> (Point( 3, 5), "icm003.def", CGI->generaltexth->zelp[381], std::bind(&CBattleControlPanel::bOptionsf,this), SDLK_o);
|
||||
@ -55,6 +56,21 @@ CBattleControlPanel::CBattleControlPanel(CBattleInterface * owner):
|
||||
tacticPhaseEnded();
|
||||
}
|
||||
|
||||
void CBattleControlPanel::show(SDL_Surface * to)
|
||||
{
|
||||
//show menu before all other elements to keep it in background
|
||||
menu->show(to);
|
||||
CIntObject::show(to);
|
||||
}
|
||||
|
||||
void CBattleControlPanel::showAll(SDL_Surface * to)
|
||||
{
|
||||
//show menu before all other elements to keep it in background
|
||||
menu->showAll(to);
|
||||
CIntObject::showAll(to);
|
||||
}
|
||||
|
||||
|
||||
void CBattleControlPanel::tacticPhaseStarted()
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
@ -63,6 +79,7 @@ void CBattleControlPanel::tacticPhaseStarted()
|
||||
btactEnd = std::make_shared<CButton>(Point(419, 4), "icm012.def", std::make_pair("", ""), [&](){ bTacticPhaseEnd();}, SDLK_RETURN);
|
||||
menu = std::make_shared<CPicture>("COPLACBR.BMP", 0, 0);
|
||||
menu->colorize(owner->curInt->playerID);
|
||||
menu->recActions &= ~(SHOWALL | UPDATE);
|
||||
}
|
||||
void CBattleControlPanel::tacticPhaseEnded()
|
||||
{
|
||||
@ -73,6 +90,7 @@ void CBattleControlPanel::tacticPhaseEnded()
|
||||
|
||||
menu = std::make_shared<CPicture>("CBAR.BMP", 0, 0);
|
||||
menu->colorize(owner->curInt->playerID);
|
||||
menu->recActions &= ~(SHOWALL | UPDATE);
|
||||
}
|
||||
|
||||
void CBattleControlPanel::bOptionsf()
|
||||
@ -82,9 +100,7 @@ void CBattleControlPanel::bOptionsf()
|
||||
|
||||
CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
|
||||
|
||||
Rect tempRect = genRect(431, 481, 160, 84);
|
||||
tempRect += pos.topLeft();
|
||||
GH.pushIntT<CBattleOptionsWindow>(tempRect, owner);
|
||||
GH.pushIntT<CBattleOptionsWindow>(owner);
|
||||
}
|
||||
|
||||
void CBattleControlPanel::bSurrenderf()
|
||||
|
@ -57,8 +57,12 @@ public:
|
||||
// unlike activate/deactivate this method will correctly grey-out all elements
|
||||
void blockUI(bool on);
|
||||
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
|
||||
void tacticPhaseStarted();
|
||||
void tacticPhaseEnded();
|
||||
|
||||
CBattleControlPanel(CBattleInterface * owner);
|
||||
CBattleControlPanel(CBattleInterface * owner, const Point & position);
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
CBattleFieldController::CBattleFieldController(CBattleInterface * owner):
|
||||
owner(owner),
|
||||
attackingHex(-1)
|
||||
attackingHex(BattleHex::INVALID)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
pos.w = owner->pos.w;
|
||||
@ -58,7 +58,14 @@ CBattleFieldController::CBattleFieldController(CBattleInterface * owner):
|
||||
cellBorders = std::make_shared<CCanvas>(Point(background->width(), background->height()));
|
||||
|
||||
for (int i=0; i<GameConstants::BFIELD_SIZE; ++i)
|
||||
{
|
||||
if ( i % GameConstants::BFIELD_WIDTH == 0)
|
||||
continue;
|
||||
if ( i % GameConstants::BFIELD_WIDTH == GameConstants::BFIELD_WIDTH - 1)
|
||||
continue;
|
||||
|
||||
cellBorders->draw(cellBorder, hexPositionLocal(i).topLeft());
|
||||
}
|
||||
|
||||
backgroundWithHexes = std::make_shared<CCanvas>(Point(background->width(), background->height()));
|
||||
|
||||
|
@ -24,19 +24,12 @@
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMessage.h"
|
||||
#include "../CMT.h"
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CVideoHandler.h"
|
||||
#include "../Graphics.h"
|
||||
#include "../gui/CAnimation.h"
|
||||
#include "../gui/CCanvas.h"
|
||||
#include "../gui/CCursorHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/SDL_Extensions.h"
|
||||
#include "../windows/CAdvmapInterface.h"
|
||||
#include "../windows/CCreatureWindow.h"
|
||||
#include "../windows/CSpellWindow.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CStack.h"
|
||||
@ -44,15 +37,7 @@
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/CondSh.h"
|
||||
#include "../../lib/CRandomGenerator.h"
|
||||
#include "../../lib/spells/CSpellHandler.h"
|
||||
#include "../../lib/spells/ISpellMechanics.h"
|
||||
#include "../../lib/spells/Problem.h"
|
||||
#include "../../lib/CTownHandler.h"
|
||||
#include "../../lib/BattleFieldHandler.h"
|
||||
#include "../../lib/ObstacleHandler.h"
|
||||
#include "../../lib/CGameState.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
#include "../../lib/NetPacks.h"
|
||||
#include "../../lib/UnlockGuard.h"
|
||||
|
||||
@ -127,10 +112,14 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
this->army1 = army1;
|
||||
this->army2 = army2;
|
||||
|
||||
controlPanel = std::make_shared<CBattleControlPanel>(this, Point(0, 556));
|
||||
|
||||
//preparing menu background and terrain
|
||||
fieldController.reset( new CBattleFieldController(this));
|
||||
stacksController.reset( new CBattleStacksController(this));
|
||||
actionsController.reset( new CBattleActionsController(this));
|
||||
effectsController.reset(new CBattleEffectsController(this));
|
||||
|
||||
|
||||
//loading hero animations
|
||||
if(hero1) // attacking hero
|
||||
@ -517,7 +506,7 @@ void CBattleInterface::spellCast(const BattleSpellCast * sc)
|
||||
{
|
||||
if(casterStack != nullptr)
|
||||
{
|
||||
srccoord = CClickableHex::getXYUnitAnim(casterStack->getPosition(), casterStack, this);
|
||||
srccoord = stacksController->getStackPositionAtHex(casterStack->getPosition(), casterStack);
|
||||
srccoord.x += 250;
|
||||
srccoord.y += 240;
|
||||
}
|
||||
@ -536,7 +525,7 @@ void CBattleInterface::spellCast(const BattleSpellCast * sc)
|
||||
//playing projectile animation
|
||||
if (sc->tile.isValid())
|
||||
{
|
||||
Point destcoord = CClickableHex::getXYUnitAnim(sc->tile, curInt->cb->battleGetStackByPos(sc->tile), this); //position attacked by projectile
|
||||
Point destcoord = stacksController->getStackPositionAtHex(sc->tile, curInt->cb->battleGetStackByPos(sc->tile)); //position attacked by projectile
|
||||
destcoord.x += 250; destcoord.y += 240;
|
||||
|
||||
//animation angle
|
||||
@ -921,7 +910,6 @@ void CBattleInterface::showAll(SDL_Surface *to)
|
||||
void CBattleInterface::show(SDL_Surface *to)
|
||||
{
|
||||
auto canvas = std::make_shared<CCanvas>(to);
|
||||
|
||||
assert(to);
|
||||
|
||||
SDL_Rect buf;
|
||||
@ -944,7 +932,7 @@ void CBattleInterface::show(SDL_Surface *to)
|
||||
}
|
||||
fieldController->showHighlightedHexes(canvas);
|
||||
|
||||
showBattlefieldObjects(to);
|
||||
showBattlefieldObjects(canvas);
|
||||
projectilesController->showProjectiles(canvas);
|
||||
|
||||
if(battleActionsStarted)
|
||||
@ -952,7 +940,7 @@ void CBattleInterface::show(SDL_Surface *to)
|
||||
|
||||
SDL_SetClipRect(to, &buf); //restoring previous clip_rect
|
||||
|
||||
showInterface(to);
|
||||
showInterface(canvas);
|
||||
|
||||
//activation of next stack, if any
|
||||
//TODO: should be moved to the very start of this method?
|
||||
@ -968,17 +956,15 @@ void CBattleInterface::showBattlefieldObjects(std::shared_ptr<CCanvas> canvas, c
|
||||
effectsController->showBattlefieldObjects(canvas, location);
|
||||
}
|
||||
|
||||
void CBattleInterface::showBattlefieldObjects(SDL_Surface *to)
|
||||
void CBattleInterface::showBattlefieldObjects(std::shared_ptr<CCanvas> canvas)
|
||||
{
|
||||
auto canvas = std::make_shared<CCanvas>(to);
|
||||
|
||||
showBattlefieldObjects(canvas, BattleHex::HEX_BEFORE_ALL);
|
||||
|
||||
// show heroes after "beforeAll" - e.g. topmost wall in siege
|
||||
if (attackingHero)
|
||||
attackingHero->show(to);
|
||||
attackingHero->show(canvas->getSurface());
|
||||
if (defendingHero)
|
||||
defendingHero->show(to);
|
||||
defendingHero->show(canvas->getSurface());
|
||||
|
||||
for (int i = 0; i < GameConstants::BFIELD_SIZE; ++i)
|
||||
showBattlefieldObjects(canvas, BattleHex(i));
|
||||
@ -986,11 +972,11 @@ void CBattleInterface::showBattlefieldObjects(SDL_Surface *to)
|
||||
showBattlefieldObjects(canvas, BattleHex::HEX_AFTER_ALL);
|
||||
}
|
||||
|
||||
void CBattleInterface::showInterface(SDL_Surface *to)
|
||||
void CBattleInterface::showInterface(std::shared_ptr<CCanvas> canvas)
|
||||
{
|
||||
//showing in-game console
|
||||
LOCPLINT->cingconsole->show(to);
|
||||
controlPanel->show(to);
|
||||
LOCPLINT->cingconsole->show(canvas->getSurface());
|
||||
controlPanel->showAll(canvas->getSurface());
|
||||
|
||||
Rect posWithQueue = Rect(pos.x, pos.y, 800, 600);
|
||||
|
||||
@ -1002,13 +988,13 @@ void CBattleInterface::showInterface(SDL_Surface *to)
|
||||
posWithQueue.h += queue->pos.h;
|
||||
}
|
||||
|
||||
queue->showAll(to);
|
||||
queue->showAll(canvas->getSurface());
|
||||
}
|
||||
|
||||
//printing border around interface
|
||||
if (screen->w != 800 || screen->h !=600)
|
||||
{
|
||||
CMessage::drawBorder(curInt->playerID,to,posWithQueue.w + 28, posWithQueue.h + 28, posWithQueue.x-14, posWithQueue.y-15);
|
||||
CMessage::drawBorder(curInt->playerID,canvas->getSurface(),posWithQueue.w + 28, posWithQueue.h + 28, posWithQueue.x-14, posWithQueue.y-15);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,9 +98,9 @@ private:
|
||||
|
||||
const CGHeroInstance *getActiveHero(); //returns hero that can currently cast a spell
|
||||
|
||||
void showInterface(SDL_Surface *to);
|
||||
void showInterface(std::shared_ptr<CCanvas> canvas);
|
||||
|
||||
void showBattlefieldObjects(SDL_Surface *to);
|
||||
void showBattlefieldObjects(std::shared_ptr<CCanvas> canvas);
|
||||
void showBattlefieldObjects(std::shared_ptr<CCanvas> canvas, const BattleHex & location );
|
||||
|
||||
void setHeroAnimation(ui8 side, int phase);
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "../gui/CAnimation.h"
|
||||
#include "../gui/CCursorHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/SDL_Extensions.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/Images.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
@ -317,13 +316,10 @@ CHeroInfoWindow::CHeroInfoWindow(const InfoAboutHero & hero, Point * position)
|
||||
labels.push_back(std::make_shared<CLabel>(39, 186, EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, std::to_string(currentSpellPoints) + "/" + std::to_string(maxSpellPoints)));
|
||||
}
|
||||
|
||||
CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface *owner)
|
||||
CBattleOptionsWindow::CBattleOptionsWindow(CBattleInterface *owner):
|
||||
CWindowObject(PLAYER_COLORED, "comopbck.bmp")
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
pos = position;
|
||||
|
||||
background = std::make_shared<CPicture>("comopbck.bmp");
|
||||
background->colorize(owner->getCurrentPlayerInterface()->playerID);
|
||||
|
||||
auto viewGrid = std::make_shared<CToggleButton>(Point(25, 56), "sysopchk.def", CGI->generaltexth->zelp[427], [=](bool on){owner->setPrintCellBorders(on);} );
|
||||
viewGrid->setSelected(settings["battle"]["cellBorders"].Bool());
|
||||
@ -577,46 +573,6 @@ void CBattleResultWindow::bExitf()
|
||||
CCS->videoh->close();
|
||||
}
|
||||
|
||||
Point CClickableHex::getXYUnitAnim(BattleHex hexNum, const CStack * stack, CBattleInterface * cbi)
|
||||
{
|
||||
assert(cbi);
|
||||
|
||||
Point ret(-500, -500); //returned value
|
||||
if(stack && stack->initialPosition < 0) //creatures in turrets
|
||||
return cbi->siegeController->getTurretCreaturePosition(stack->initialPosition);
|
||||
|
||||
static const Point basePos(-190, -139); // position of creature in topleft corner
|
||||
static const int imageShiftX = 30; // X offset to base pos for facing right stacks, negative for facing left
|
||||
|
||||
ret.x = basePos.x + 22 * ( (hexNum.getY() + 1)%2 ) + 44 * hexNum.getX();
|
||||
ret.y = basePos.y + 42 * hexNum.getY();
|
||||
|
||||
if (stack)
|
||||
{
|
||||
if(cbi->stacksController->facingRight(stack))
|
||||
ret.x += imageShiftX;
|
||||
else
|
||||
ret.x -= imageShiftX;
|
||||
|
||||
//shifting position for double - hex creatures
|
||||
if(stack->doubleWide())
|
||||
{
|
||||
if(stack->side == BattleSide::ATTACKER)
|
||||
{
|
||||
if(cbi->stacksController->facingRight(stack))
|
||||
ret.x -= 44;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!cbi->stacksController->facingRight(stack))
|
||||
ret.x += 44;
|
||||
}
|
||||
}
|
||||
}
|
||||
//returning
|
||||
return ret + CPlayerInterface::battleInt->pos;
|
||||
}
|
||||
|
||||
void CClickableHex::hover(bool on)
|
||||
{
|
||||
hovered = on;
|
||||
|
@ -98,17 +98,16 @@ public:
|
||||
};
|
||||
|
||||
/// Class which manages the battle options window
|
||||
class CBattleOptionsWindow : public WindowBase
|
||||
class CBattleOptionsWindow : public CWindowObject
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<CPicture> background;
|
||||
std::shared_ptr<CButton> setToDefault;
|
||||
std::shared_ptr<CButton> exit;
|
||||
std::shared_ptr<CToggleGroup> animSpeeds;
|
||||
std::vector<std::shared_ptr<CLabel>> labels;
|
||||
std::vector<std::shared_ptr<CToggleButton>> toggles;
|
||||
public:
|
||||
CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface * owner);
|
||||
CBattleOptionsWindow(CBattleInterface * owner);
|
||||
|
||||
void bDefaultf(); //default button callback
|
||||
void bExitf(); //exit button callback
|
||||
@ -146,11 +145,6 @@ public:
|
||||
bool strictHovered; //for determining if hex is hovered by mouse (this is different problem than hex's graphic hovering)
|
||||
CBattleInterface * myInterface; //interface that owns me
|
||||
|
||||
/// returns (x, y) of left top corner of animation
|
||||
/// FIXME: move someplace else?
|
||||
/// FIXME: some usages should be replaced with creAnims->pos?
|
||||
static Point getXYUnitAnim(BattleHex hexNum, const CStack * creature, CBattleInterface * cbi);
|
||||
|
||||
//for user interactions
|
||||
void hover (bool on) override;
|
||||
void mouseMoved (const SDL_MouseMotionEvent &sEvent) override;
|
||||
|
@ -130,7 +130,7 @@ void CBattleObstacleController::showBattlefieldObjects(std::shared_ptr<CCanvas>
|
||||
if (obstacle->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
|
||||
continue;
|
||||
|
||||
if (obstacle->obstacleType != CObstacleInstance::MOAT)
|
||||
if (obstacle->obstacleType == CObstacleInstance::MOAT)
|
||||
continue;
|
||||
|
||||
if ( obstacle->pos != location)
|
||||
|
@ -341,7 +341,7 @@ void CBattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
|
||||
//no attacker stack, assume spell-related (earthquake) - only hit animation
|
||||
for (auto attackInfo : ca.attackedParts)
|
||||
{
|
||||
Point destPos = CClickableHex::getXYUnitAnim(attackInfo.destinationTile, nullptr, owner) + Point(99, 120);
|
||||
Point destPos = owner->stacksController->getStackPositionAtHex(attackInfo.destinationTile, nullptr) + Point(99, 120);
|
||||
|
||||
owner->stacksController->addNewAnim(new CEffectAnimation(owner, "SGEXPL.DEF", destPos.x, destPos.y));
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "CBattleProjectileController.h"
|
||||
#include "CBattleControlPanel.h"
|
||||
#include "../gui/CAnimation.h"
|
||||
#include "../gui/SDL_Extensions.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/CCanvas.h"
|
||||
#include "../../lib/battle/BattleHex.h"
|
||||
@ -58,7 +57,14 @@ static void onAnimationFinished(const CStack *stack, std::weak_ptr<CCreatureAnim
|
||||
}
|
||||
|
||||
CBattleStacksController::CBattleStacksController(CBattleInterface * owner):
|
||||
owner(owner)
|
||||
owner(owner),
|
||||
activeStack(nullptr),
|
||||
mouseHoveredStack(nullptr),
|
||||
stackToActivate(nullptr),
|
||||
selectedStack(nullptr),
|
||||
stackCanCastSpell(false),
|
||||
creatureSpellToCast(uint32_t(-1)),
|
||||
animIDhelper(0)
|
||||
{
|
||||
//preparing graphics for displaying amounts of creatures
|
||||
amountNormal = IImage::createFromFile("CMNUMWIN.BMP");
|
||||
@ -66,10 +72,10 @@ CBattleStacksController::CBattleStacksController(CBattleInterface * owner):
|
||||
amountNegative = IImage::createFromFile("CMNUMWIN.BMP");
|
||||
amountEffNeutral = IImage::createFromFile("CMNUMWIN.BMP");
|
||||
|
||||
ColorShifterAddMulExcept shifterNormal ({0,0,0,0}, {150, 48, 237, 255}, {132, 231, 255, 255});
|
||||
ColorShifterAddMulExcept shifterPositive({0,0,0,0}, { 45, 255, 45, 255}, {132, 231, 255, 255});
|
||||
ColorShifterAddMulExcept shifterNegative({0,0,0,0}, {255, 45, 45, 255}, {132, 231, 255, 255});
|
||||
ColorShifterAddMulExcept shifterNeutral ({0,0,0,0}, {255, 255, 45, 255}, {132, 231, 255, 255});
|
||||
ColorShifterAddMulExcept shifterNormal ({0,0,0,0}, {150, 50, 255, 255}, {255, 231, 132, 255});
|
||||
ColorShifterAddMulExcept shifterPositive({0,0,0,0}, { 50, 255, 50, 255}, {255, 231, 132, 255});
|
||||
ColorShifterAddMulExcept shifterNegative({0,0,0,0}, {255, 50, 50, 255}, {255, 231, 132, 255});
|
||||
ColorShifterAddMulExcept shifterNeutral ({0,0,0,0}, {255, 255, 50, 255}, {255, 231, 132, 255});
|
||||
|
||||
amountNormal->adjustPalette(&shifterNormal);
|
||||
amountPositive->adjustPalette(&shifterPositive);
|
||||
@ -119,8 +125,8 @@ void CBattleStacksController::showBattlefieldObjects(std::shared_ptr<CCanvas> ca
|
||||
if (creAnims[stack->ID]->isDead())
|
||||
{
|
||||
//if ( location == stack->getPosition() )
|
||||
if ( location == BattleHex::HEX_BEFORE_ALL ) //FIXME: any cases when this won't work?
|
||||
{};
|
||||
if ( location == BattleHex::HEX_BEFORE_ALL ) //FIXME: any cases when using BEFORE_ALL won't work?
|
||||
showStack(canvas, stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -128,7 +134,7 @@ void CBattleStacksController::showBattlefieldObjects(std::shared_ptr<CCanvas> ca
|
||||
if (!creAnims[stack->ID]->isMoving())
|
||||
{
|
||||
if ( location == stack->getPosition() )
|
||||
{};
|
||||
showStack(canvas, stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -136,14 +142,14 @@ void CBattleStacksController::showBattlefieldObjects(std::shared_ptr<CCanvas> ca
|
||||
if (stack->hasBonusOfType(Bonus::FLYING))
|
||||
{
|
||||
if ( location == BattleHex::HEX_AFTER_ALL)
|
||||
{};
|
||||
showStack(canvas, stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
// else - unit moving on ground
|
||||
{
|
||||
if ( location == getCurrentPosition(stack) )
|
||||
{};
|
||||
showStack(canvas, stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -177,7 +183,7 @@ void CBattleStacksController::stackAdded(const CStack * stack)
|
||||
{
|
||||
creDir[stack->ID] = stack->side == BattleSide::ATTACKER; // must be set before getting stack position
|
||||
|
||||
Point coords = CClickableHex::getXYUnitAnim(stack->getPosition(), stack, owner);
|
||||
Point coords = getStackPositionAtHex(stack->getPosition(), stack);
|
||||
|
||||
if(stack->initialPosition < 0) //turret
|
||||
{
|
||||
@ -396,7 +402,7 @@ void CBattleStacksController::stackRemoved(uint32_t stackID)
|
||||
BattleAction *action = new BattleAction();
|
||||
action->side = owner->defendingHeroInstance ? (owner->curInt->playerID == owner->defendingHeroInstance->tempOwner) : false;
|
||||
action->actionType = EActionType::CANCEL;
|
||||
action->stackNumber = owner->stacksController->getActiveStack()->ID;
|
||||
action->stackNumber = getActiveStack()->ID;
|
||||
owner->givenCommand.setn(action);
|
||||
setActiveStack(nullptr);
|
||||
}
|
||||
@ -448,8 +454,8 @@ void CBattleStacksController::stackAttacking( const CStack *attacker, BattleHex
|
||||
|
||||
bool CBattleStacksController::shouldRotate(const CStack * stack, const BattleHex & oldPos, const BattleHex & nextHex)
|
||||
{
|
||||
Point begPosition = CClickableHex::getXYUnitAnim(oldPos,stack, owner);
|
||||
Point endPosition = CClickableHex::getXYUnitAnim(nextHex, stack, owner);
|
||||
Point begPosition = getStackPositionAtHex(oldPos,stack);
|
||||
Point endPosition = getStackPositionAtHex(nextHex, stack);
|
||||
|
||||
if((begPosition.x > endPosition.x) && facingRight(stack))
|
||||
return true;
|
||||
@ -510,7 +516,7 @@ void CBattleStacksController::activateStack()
|
||||
setActiveStack(stackToActivate);
|
||||
stackToActivate = nullptr;
|
||||
|
||||
const CStack * s = owner->stacksController->getActiveStack();
|
||||
const CStack * s = getActiveStack();
|
||||
if(!s)
|
||||
return;
|
||||
|
||||
@ -565,3 +571,42 @@ SpellID CBattleStacksController::activeStackSpellToCast()
|
||||
return SpellID::NONE;
|
||||
return SpellID(creatureSpellToCast);
|
||||
}
|
||||
|
||||
Point CBattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CStack * stack)
|
||||
{
|
||||
Point ret(-500, -500); //returned value
|
||||
if(stack && stack->initialPosition < 0) //creatures in turrets
|
||||
return owner->siegeController->getTurretCreaturePosition(stack->initialPosition);
|
||||
|
||||
static const Point basePos(-190, -139); // position of creature in topleft corner
|
||||
static const int imageShiftX = 30; // X offset to base pos for facing right stacks, negative for facing left
|
||||
|
||||
ret.x = basePos.x + 22 * ( (hexNum.getY() + 1)%2 ) + 44 * hexNum.getX();
|
||||
ret.y = basePos.y + 42 * hexNum.getY();
|
||||
|
||||
if (stack)
|
||||
{
|
||||
if(facingRight(stack))
|
||||
ret.x += imageShiftX;
|
||||
else
|
||||
ret.x -= imageShiftX;
|
||||
|
||||
//shifting position for double - hex creatures
|
||||
if(stack->doubleWide())
|
||||
{
|
||||
if(stack->side == BattleSide::ATTACKER)
|
||||
{
|
||||
if(facingRight(stack))
|
||||
ret.x -= 44;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!facingRight(stack))
|
||||
ret.x += 44;
|
||||
}
|
||||
}
|
||||
}
|
||||
//returning
|
||||
return ret + owner->pos.topLeft();
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../gui/Geometries.h"
|
||||
|
||||
struct BattleObjectsByHex;
|
||||
struct SDL_Surface;
|
||||
struct BattleHex;
|
||||
@ -89,5 +91,8 @@ public:
|
||||
const CStack* getActiveStack();
|
||||
const CStack* getSelectedStack();
|
||||
|
||||
/// returns position of animation needed to place stack in specific hex
|
||||
Point getStackPositionAtHex(BattleHex hexNum, const CStack * creature);
|
||||
|
||||
friend class CBattleAnimation; // for exposing pendingAnims/creAnims/creDir to animations
|
||||
};
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/CCreatureHandler.h"
|
||||
|
||||
#include "../gui/SDL_Extensions.h"
|
||||
#include "../gui/CCanvas.h"
|
||||
|
||||
static const SDL_Color creatureBlueBorder = { 0, 255, 255, 255 };
|
||||
|
@ -188,24 +188,6 @@ Uint32 CSDL_Ext::SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y
|
||||
}
|
||||
}
|
||||
|
||||
void CSDL_Ext::alphaTransform(SDL_Surface *src)
|
||||
{
|
||||
assert(src->format->BitsPerPixel == 8);
|
||||
SDL_Color colors[] =
|
||||
{
|
||||
{ 0, 0, 0, 0}, { 0, 0, 0, 32}, { 0, 0, 0, 64},
|
||||
{ 0, 0, 0, 128}, { 0, 0, 0, 128}
|
||||
};
|
||||
|
||||
|
||||
for (size_t i=0; i< ARRAY_COUNT(colors); i++ )
|
||||
{
|
||||
SDL_Color & palColor = src->format->palette->colors[i];
|
||||
palColor = colors[i];
|
||||
}
|
||||
SDL_SetColorKey(src, SDL_TRUE, 0);
|
||||
}
|
||||
|
||||
template<int bpp>
|
||||
int CSDL_Ext::blit8bppAlphaTo24bppT(const SDL_Surface * src, const SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect)
|
||||
{
|
||||
|
@ -197,7 +197,8 @@ class ColorShifterAddMulExcept : public ColorShifterAddMul
|
||||
SDL_Color ignored;
|
||||
public:
|
||||
ColorShifterAddMulExcept(SDL_Color add, SDL_Color mul, SDL_Color ignored) :
|
||||
ColorShifterAddMul(add, mul)
|
||||
ColorShifterAddMul(add, mul),
|
||||
ignored(ignored)
|
||||
{}
|
||||
|
||||
SDL_Color shiftColor(SDL_Color input) const override
|
||||
@ -241,7 +242,6 @@ namespace CSDL_Ext
|
||||
SDL_Surface * verticalFlip(SDL_Surface * toRot); //vertical flip
|
||||
SDL_Surface * horizontalFlip(SDL_Surface * toRot); //horizontal flip
|
||||
Uint32 SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte = false);
|
||||
void alphaTransform(SDL_Surface * src); //adds transparency and shadows (partial handling only; see examples of using for details)
|
||||
bool isTransparent(SDL_Surface * srf, int x, int y); //checks if surface is transparent at given position
|
||||
|
||||
Uint8 *getPxPtr(const SDL_Surface * const &srf, const int x, const int y);
|
||||
|
Loading…
Reference in New Issue
Block a user