mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
Merge pull request #1792 from IvanSavenko/happy_dydzio
Fixes for beta - graphical artifacts
This commit is contained in:
commit
974be97e6d
@ -38,7 +38,6 @@
|
||||
"name" : "Ключевые файлы VCMI",
|
||||
"description" : "Файлы, необходимые для полноценной работы VCMI",
|
||||
"author" : "Команда VCMI",
|
||||
"modType" : "Графический",
|
||||
|
||||
"skipValidation" : true,
|
||||
"translations" : [
|
||||
|
@ -2033,7 +2033,7 @@ bool CPlayerInterface::capturedAllEvents()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool needToLockAdventureMap = adventureInt->active && CGI->mh->hasOngoingAnimations();
|
||||
bool needToLockAdventureMap = adventureInt && adventureInt->active && CGI->mh->hasOngoingAnimations();
|
||||
|
||||
if (ignoreEvents || needToLockAdventureMap)
|
||||
{
|
||||
|
@ -694,14 +694,14 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B
|
||||
if (action.spell() == SpellID::SACRIFICE)
|
||||
{
|
||||
heroSpellToCast->aimToHex(targetHex);
|
||||
possibleActions.push_back(PossiblePlayerBattleAction::SACRIFICE);
|
||||
possibleActions.push_back({PossiblePlayerBattleAction::SACRIFICE, action.spell()});
|
||||
owner.stacksController->setSelectedStack(targetStack);
|
||||
return;
|
||||
}
|
||||
if (action.spell() == SpellID::TELEPORT)
|
||||
{
|
||||
heroSpellToCast->aimToUnit(targetStack);
|
||||
possibleActions.push_back(PossiblePlayerBattleAction::TELEPORT);
|
||||
possibleActions.push_back({PossiblePlayerBattleAction::TELEPORT, action.spell()});
|
||||
owner.stacksController->setSelectedStack(targetStack);
|
||||
return;
|
||||
}
|
||||
|
@ -35,8 +35,6 @@
|
||||
#include "../../lib/CStack.h"
|
||||
#include "../../lib/spells/ISpellMechanics.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
BattleFieldController::BattleFieldController(BattleInterface & owner):
|
||||
owner(owner)
|
||||
{
|
||||
@ -67,10 +65,7 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
|
||||
|
||||
backgroundWithHexes = std::make_unique<Canvas>(Point(background->width(), background->height()));
|
||||
|
||||
auto accessibility = owner.curInt->cb->getAccesibility();
|
||||
for(int i = 0; i < accessibility.size(); i++)
|
||||
stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
|
||||
|
||||
updateAccessibleHexes();
|
||||
addUsedEvents(LCLICK | RCLICK | MOVE);
|
||||
LOCPLINT->cingconsole->pos = this->pos;
|
||||
}
|
||||
@ -180,11 +175,6 @@ void BattleFieldController::redrawBackgroundWithHexes()
|
||||
if (activeStack)
|
||||
occupyableHexes = owner.curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes);
|
||||
|
||||
auto accessibility = owner.curInt->cb->getAccesibility();
|
||||
|
||||
for(int i = 0; i < accessibility.size(); i++)
|
||||
stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
|
||||
|
||||
//prepare background graphic with hexes and shaded hexes
|
||||
backgroundWithHexes->draw(background, Point(0,0));
|
||||
owner.obstacleController->showAbsoluteObstacles(*backgroundWithHexes);
|
||||
@ -579,6 +569,14 @@ bool BattleFieldController::isTileAttackable(const BattleHex & number) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void BattleFieldController::updateAccessibleHexes()
|
||||
{
|
||||
auto accessibility = owner.curInt->cb->getAccesibility();
|
||||
|
||||
for(int i = 0; i < accessibility.size(); i++)
|
||||
stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE || (accessibility[i] == EAccessibility::SIDE_COLUMN));
|
||||
}
|
||||
|
||||
bool BattleFieldController::stackCountOutsideHex(const BattleHex & number) const
|
||||
{
|
||||
return stackCountOutsideHexes[number];
|
||||
@ -591,6 +589,7 @@ void BattleFieldController::showAll(SDL_Surface * to)
|
||||
|
||||
void BattleFieldController::show(SDL_Surface * to)
|
||||
{
|
||||
updateAccessibleHexes();
|
||||
owner.stacksController->update();
|
||||
owner.obstacleController->update();
|
||||
|
||||
|
@ -56,6 +56,7 @@ class BattleFieldController : public CIntObject
|
||||
void showBackgroundImage(Canvas & canvas);
|
||||
void showBackgroundImageWithHexes(Canvas & canvas);
|
||||
void showHighlightedHexes(Canvas & canvas);
|
||||
void updateAccessibleHexes();
|
||||
|
||||
BattleHex::EDir selectAttackDirection(BattleHex myNumber, const Point & point);
|
||||
|
||||
|
@ -267,12 +267,8 @@ bool BattleStacksController::stackNeedsAmountBox(const CStack * stack) const
|
||||
return false;
|
||||
|
||||
// if stack has any ongoing animation - hide the box
|
||||
for(auto anim : currentAnimations)
|
||||
{
|
||||
auto stackAnimation = dynamic_cast<BattleStackAnimation*>(anim);
|
||||
if(stackAnimation && (stackAnimation->stack->ID == stack->ID))
|
||||
return false;
|
||||
}
|
||||
if (stackAmountBoxHidden.count(stack->ID))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -300,26 +296,42 @@ std::shared_ptr<IImage> BattleStacksController::getStackAmountBox(const CStack *
|
||||
|
||||
void BattleStacksController::showStackAmountBox(Canvas & canvas, const CStack * stack)
|
||||
{
|
||||
//blitting amount background box
|
||||
auto amountBG = getStackAmountBox(stack);
|
||||
|
||||
const int sideShift = stack->side == BattleSide::ATTACKER ? 1 : -1;
|
||||
const int reverseSideShift = stack->side == BattleSide::ATTACKER ? -1 : 1;
|
||||
const BattleHex nextPos = stack->getPosition() + sideShift;
|
||||
const bool edge = stack->getPosition() % GameConstants::BFIELD_WIDTH == (stack->side == BattleSide::ATTACKER ? GameConstants::BFIELD_WIDTH - 2 : 1);
|
||||
const bool moveInside = !edge && !owner.fieldController->stackCountOutsideHex(nextPos);
|
||||
bool doubleWide = stack->doubleWide();
|
||||
bool turnedRight = facingRight(stack);
|
||||
bool attacker = stack->side == BattleSide::ATTACKER;
|
||||
|
||||
int xAdd = (stack->side == BattleSide::ATTACKER ? 220 : 202) +
|
||||
(stack->doubleWide() ? 44 : 0) * sideShift +
|
||||
(moveInside ? amountBG->width() + 10 : 0) * reverseSideShift;
|
||||
int yAdd = 260 + ((stack->side == BattleSide::ATTACKER || moveInside) ? 0 : -15);
|
||||
BattleHex stackPos = stack->getPosition();
|
||||
|
||||
canvas.draw(amountBG, stackAnimation[stack->ID]->pos.topLeft() + Point(xAdd, yAdd));
|
||||
// double-wide unit turned around - use opposite hex for stack label
|
||||
if (doubleWide && turnedRight != attacker)
|
||||
stackPos = stack->occupiedHex();
|
||||
|
||||
//blitting amount
|
||||
Point textPos = stackAnimation[stack->ID]->pos.topLeft() + amountBG->dimensions()/2 + Point(xAdd, yAdd);
|
||||
BattleHex frontPos = turnedRight ?
|
||||
stackPos.cloneInDirection(BattleHex::RIGHT) :
|
||||
stackPos.cloneInDirection(BattleHex::LEFT);
|
||||
|
||||
canvas.drawText(textPos, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::CENTER, TextOperations::formatMetric(stack->getCount(), 4));
|
||||
bool moveInside = !owner.fieldController->stackCountOutsideHex(frontPos);
|
||||
|
||||
Point boxPosition;
|
||||
|
||||
if (moveInside)
|
||||
{
|
||||
boxPosition = owner.fieldController->hexPositionLocal(stackPos).center() + Point(-15, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (turnedRight)
|
||||
boxPosition = owner.fieldController->hexPositionLocal(frontPos).center() + Point (-22, 1);
|
||||
else
|
||||
boxPosition = owner.fieldController->hexPositionLocal(frontPos).center() + Point(-8, -14);
|
||||
}
|
||||
|
||||
Point textPosition = amountBG->dimensions()/2 + boxPosition;
|
||||
|
||||
canvas.draw(amountBG, boxPosition);
|
||||
canvas.drawText(textPosition, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::CENTER, TextOperations::formatMetric(stack->getCount(), 4));
|
||||
}
|
||||
|
||||
void BattleStacksController::showStack(Canvas & canvas, const CStack * stack)
|
||||
@ -368,6 +380,7 @@ void BattleStacksController::updateBattleAnimations()
|
||||
|
||||
if (hadAnimations && currentAnimations.empty())
|
||||
{
|
||||
//stackAmountBoxHidden.clear();
|
||||
owner.executeStagedAnimations();
|
||||
if (currentAnimations.empty())
|
||||
owner.onAnimationsFinished();
|
||||
@ -378,8 +391,15 @@ void BattleStacksController::updateBattleAnimations()
|
||||
|
||||
void BattleStacksController::addNewAnim(BattleAnimation *anim)
|
||||
{
|
||||
if (currentAnimations.empty())
|
||||
stackAmountBoxHidden.clear();
|
||||
|
||||
owner.onAnimationsStarted();
|
||||
currentAnimations.push_back(anim);
|
||||
|
||||
auto stackAnimation = dynamic_cast<BattleStackAnimation*>(anim);
|
||||
if(stackAnimation)
|
||||
stackAmountBoxHidden.insert(stackAnimation->stack->ID);
|
||||
}
|
||||
|
||||
void BattleStacksController::stackRemoved(uint32_t stackID)
|
||||
@ -668,6 +688,8 @@ void BattleStacksController::endAction(const BattleAction* action)
|
||||
owner.executeStagedAnimations();
|
||||
owner.waitForAnimations();
|
||||
|
||||
stackAmountBoxHidden.clear();
|
||||
|
||||
owner.windowObject->blockUI(activeStack == nullptr);
|
||||
removeExpiredColorFilters();
|
||||
}
|
||||
@ -738,8 +760,8 @@ Point BattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CSta
|
||||
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
|
||||
static const Point basePos(-189, -139); // position of creature in topleft corner
|
||||
static const int imageShiftX = 29; // 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();
|
||||
|
@ -67,6 +67,9 @@ class BattleStacksController
|
||||
/// <creatureID, if false reverse creature's animation> //TODO: move it to battle callback
|
||||
std::map<int, bool> stackFacingRight;
|
||||
|
||||
/// Stacks have amount box hidden due to ongoing animations
|
||||
std::set<int> stackAmountBoxHidden;
|
||||
|
||||
/// currently active stack; nullptr - no one
|
||||
const CStack *activeStack;
|
||||
|
||||
|
@ -66,16 +66,18 @@ void BasicMapView::render(Canvas & target, bool fullUpdate)
|
||||
|
||||
void BasicMapView::show(SDL_Surface * to)
|
||||
{
|
||||
controller->update(GH.mainFPSmng->getElapsedMilliseconds());
|
||||
controller->updateBefore(GH.mainFPSmng->getElapsedMilliseconds());
|
||||
|
||||
Canvas target(to);
|
||||
CSDL_Ext::CClipRectGuard guard(to, pos);
|
||||
render(target, false);
|
||||
|
||||
controller->updateAfter(GH.mainFPSmng->getElapsedMilliseconds());
|
||||
}
|
||||
|
||||
void BasicMapView::showAll(SDL_Surface * to)
|
||||
{
|
||||
controller->update(0);
|
||||
controller->updateBefore(0);
|
||||
|
||||
Canvas target(to);
|
||||
CSDL_Ext::CClipRectGuard guard(to, pos);
|
||||
|
@ -88,7 +88,7 @@ std::shared_ptr<IMapRendererContext> MapViewController::getContext() const
|
||||
return context;
|
||||
}
|
||||
|
||||
void MapViewController::update(uint32_t timeDelta)
|
||||
void MapViewController::updateBefore(uint32_t timeDelta)
|
||||
{
|
||||
// confirmed to match H3 for
|
||||
// - hero embarking on boat (500 ms)
|
||||
@ -116,56 +116,32 @@ void MapViewController::update(uint32_t timeDelta)
|
||||
settings["adventure"]["enemyMoveTime"].Float();
|
||||
|
||||
movementContext->progress += timeDelta / heroMoveTime;
|
||||
movementContext->progress = std::min( 1.0, movementContext->progress);
|
||||
|
||||
Point positionFrom = Point(hero->convertToVisitablePos(movementContext->tileFrom)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
|
||||
Point positionDest = Point(hero->convertToVisitablePos(movementContext->tileDest)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
|
||||
|
||||
Point positionCurr = vstd::lerp(positionFrom, positionDest, movementContext->progress);
|
||||
|
||||
if(movementContext->progress >= 1.0)
|
||||
{
|
||||
setViewCenter(hero->getSightCenter());
|
||||
|
||||
removeObject(context->getObject(movementContext->target));
|
||||
addObject(context->getObject(movementContext->target));
|
||||
|
||||
activateAdventureContext(movementContext->animationTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
setViewCenter(positionCurr, movementContext->tileDest.z);
|
||||
}
|
||||
setViewCenter(positionCurr, movementContext->tileDest.z);
|
||||
}
|
||||
|
||||
if(teleportContext)
|
||||
{
|
||||
teleportContext->progress += timeDelta / heroTeleportDuration;
|
||||
if(teleportContext->progress >= 1.0)
|
||||
{
|
||||
activateAdventureContext(teleportContext->animationTime);
|
||||
}
|
||||
teleportContext->progress = std::min( 1.0, teleportContext->progress);
|
||||
}
|
||||
|
||||
if(fadingOutContext)
|
||||
{
|
||||
fadingOutContext->progress -= timeDelta / fadeOutDuration;
|
||||
|
||||
if(fadingOutContext->progress <= 0.0)
|
||||
{
|
||||
removeObject(context->getObject(fadingOutContext->target));
|
||||
|
||||
activateAdventureContext(fadingOutContext->animationTime);
|
||||
}
|
||||
fadingOutContext->progress = std::max( 0.0, fadingOutContext->progress);
|
||||
}
|
||||
|
||||
if(fadingInContext)
|
||||
{
|
||||
fadingInContext->progress += timeDelta / fadeInDuration;
|
||||
|
||||
if(fadingInContext->progress >= 1.0)
|
||||
{
|
||||
activateAdventureContext(fadingInContext->animationTime);
|
||||
}
|
||||
fadingInContext->progress = std::min( 1.0, fadingInContext->progress);
|
||||
}
|
||||
|
||||
if(adventureContext)
|
||||
@ -180,6 +156,48 @@ void MapViewController::update(uint32_t timeDelta)
|
||||
}
|
||||
}
|
||||
|
||||
void MapViewController::updateAfter(uint32_t timeDelta)
|
||||
{
|
||||
if(movementContext)
|
||||
{
|
||||
const auto * object = context->getObject(movementContext->target);
|
||||
const auto * hero = dynamic_cast<const CGHeroInstance *>(object);
|
||||
const auto * boat = dynamic_cast<const CGBoat *>(object);
|
||||
|
||||
assert(boat || hero);
|
||||
|
||||
if(!hero)
|
||||
hero = boat->hero;
|
||||
|
||||
if(movementContext->progress >= 1.0)
|
||||
{
|
||||
setViewCenter(hero->getSightCenter());
|
||||
|
||||
removeObject(context->getObject(movementContext->target));
|
||||
addObject(context->getObject(movementContext->target));
|
||||
|
||||
activateAdventureContext(movementContext->animationTime);
|
||||
}
|
||||
}
|
||||
|
||||
if(teleportContext && teleportContext->progress >= 1.0)
|
||||
{
|
||||
activateAdventureContext(teleportContext->animationTime);
|
||||
}
|
||||
|
||||
if(fadingOutContext && fadingOutContext->progress <= 0.0)
|
||||
{
|
||||
removeObject(context->getObject(fadingOutContext->target));
|
||||
|
||||
activateAdventureContext(fadingOutContext->animationTime);
|
||||
}
|
||||
|
||||
if(fadingInContext && fadingInContext->progress >= 1.0)
|
||||
{
|
||||
activateAdventureContext(fadingInContext->animationTime);
|
||||
}
|
||||
}
|
||||
|
||||
bool MapViewController::isEventVisible(const CGObjectInstance * obj)
|
||||
{
|
||||
if(adventureContext == nullptr)
|
||||
|
@ -83,7 +83,8 @@ public:
|
||||
void setViewCenter(const int3 & position);
|
||||
void setViewCenter(const Point & position, int level);
|
||||
void setTileSize(const Point & tileSize);
|
||||
void update(uint32_t timeDelta);
|
||||
void updateBefore(uint32_t timeDelta);
|
||||
void updateAfter(uint32_t timeDelta);
|
||||
|
||||
void activateAdventureContext(uint32_t animationTime);
|
||||
void activateAdventureContext();
|
||||
|
Loading…
x
Reference in New Issue
Block a user