diff --git a/client/CMT.cpp b/client/CMT.cpp index 2915d2884..ad36424dd 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -468,10 +468,9 @@ int main(int argc, char * argv[]) if(!settings["session"]["headless"].Bool()) { pomtime.getDiff(); - CCS->curh = new CCursorHandler(); - graphics = new Graphics(); // should be before curh->init() + graphics = new Graphics(); // should be before curh - CCS->curh->initCursor(); + CCS->curh = new CCursorHandler(); logGlobal->info("Screen handler: %d ms", pomtime.getDiff()); pomtime.getDiff(); @@ -1581,7 +1580,7 @@ void handleQuit(bool ask) if(CSH->client && LOCPLINT && ask) { - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], [](){ // Workaround for assertion failure on exit: // handleQuit() is alway called during SDL event processing diff --git a/client/battle/BattleActionsController.cpp b/client/battle/BattleActionsController.cpp index 1617f3586..10d9498bf 100644 --- a/client/battle/BattleActionsController.cpp +++ b/client/battle/BattleActionsController.cpp @@ -60,7 +60,7 @@ void BattleActionsController::endCastingSpell() currentSpell = nullptr; spellDestSelectMode = false; - CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); + CCS->curh->set(Cursor::Combat::POINTER); if(owner.stacksController->getActiveStack()) { @@ -122,7 +122,7 @@ void BattleActionsController::enterCreatureCastingMode() owner.giveCommand(EActionType::MONSTER_SPELL, BattleHex::INVALID, owner.stacksController->activeStackSpellToCast()); owner.stacksController->setSelectedStack(nullptr); - CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); + CCS->curh->set(Cursor::Combat::POINTER); } } else @@ -245,8 +245,8 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) std::string newConsoleMsg; //used when hovering -> tooltip message and cursor to be set bool setCursor = true; //if we want to suppress setting cursor - ECursor::ECursorTypes cursorType = ECursor::COMBAT; - int cursorFrame = ECursor::COMBAT_POINTER; //TODO: is this line used? + bool spellcastingCursor = false; + auto cursorFrame = Cursor::Combat::POINTER; //used when l-clicking -> action to be called upon the click std::function realizeAction; @@ -431,12 +431,12 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) case PossiblePlayerBattleAction::MOVE_STACK: if (owner.stacksController->getActiveStack()->hasBonusOfType(Bonus::FLYING)) { - cursorFrame = ECursor::COMBAT_FLY; + cursorFrame = Cursor::Combat::FLY; newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[295]) % owner.stacksController->getActiveStack()->getName()).str(); //Fly %s here } else { - cursorFrame = ECursor::COMBAT_MOVE; + cursorFrame = Cursor::Combat::MOVE; newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[294]) % owner.stacksController->getActiveStack()->getName()).str(); //Move %s here } @@ -484,9 +484,9 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) case PossiblePlayerBattleAction::SHOOT: { if (owner.curInt->cb->battleHasShootingPenalty(owner.stacksController->getActiveStack(), myNumber)) - cursorFrame = ECursor::COMBAT_SHOOT_PENALTY; + cursorFrame = Cursor::Combat::SHOOT_PENALTY; else - cursorFrame = ECursor::COMBAT_SHOOT; + cursorFrame = Cursor::Combat::SHOOT; realizeAction = [=](){owner.giveCommand(EActionType::SHOOT, myNumber);}; TDmgRange damage = owner.curInt->cb->battleEstimateDamage(owner.stacksController->getActiveStack(), shere); @@ -521,7 +521,7 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) break; case PossiblePlayerBattleAction::TELEPORT: newConsoleMsg = CGI->generaltexth->allTexts[25]; //Teleport Here - cursorFrame = ECursor::COMBAT_TELEPORT; + cursorFrame = Cursor::Combat::TELEPORT; isCastingPossible = true; break; case PossiblePlayerBattleAction::OBSTACLE: @@ -531,7 +531,7 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) break; case PossiblePlayerBattleAction::SACRIFICE: newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[549]) % shere->getName()).str(); //sacrifice the %s - cursorFrame = ECursor::COMBAT_SACRIFICE; + cursorFrame = Cursor::Combat::SACRIFICE; isCastingPossible = true; break; case PossiblePlayerBattleAction::FREE_LOCATION: @@ -539,24 +539,24 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) isCastingPossible = true; break; case PossiblePlayerBattleAction::HEAL: - cursorFrame = ECursor::COMBAT_HEAL; + cursorFrame = Cursor::Combat::HEAL; newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[419]) % shere->getName()).str(); //Apply first aid to the %s realizeAction = [=](){ owner.giveCommand(EActionType::STACK_HEAL, myNumber); }; //command healing break; case PossiblePlayerBattleAction::RISE_DEMONS: - cursorType = ECursor::SPELLBOOK; + spellcastingCursor = true; realizeAction = [=]() { owner.giveCommand(EActionType::DAEMON_SUMMONING, myNumber); }; break; case PossiblePlayerBattleAction::CATAPULT: - cursorFrame = ECursor::COMBAT_SHOOT_CATAPULT; + cursorFrame = Cursor::Combat::SHOOT_CATAPULT; realizeAction = [=](){ owner.giveCommand(EActionType::CATAPULT, myNumber); }; break; case PossiblePlayerBattleAction::CREATURE_INFO: { - cursorFrame = ECursor::COMBAT_QUERY; + cursorFrame = Cursor::Combat::QUERY; newConsoleMsg = (boost::format(CGI->generaltexth->allTexts[297]) % shere->getName()).str(); realizeAction = [=](){ GH.pushIntT(shere, false); }; break; @@ -569,25 +569,25 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) { case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE: case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL: - cursorFrame = ECursor::COMBAT_BLOCKED; + cursorFrame = Cursor::Combat::BLOCKED; newConsoleMsg = CGI->generaltexth->allTexts[23]; break; case PossiblePlayerBattleAction::TELEPORT: - cursorFrame = ECursor::COMBAT_BLOCKED; + cursorFrame = Cursor::Combat::BLOCKED; newConsoleMsg = CGI->generaltexth->allTexts[24]; //Invalid Teleport Destination break; case PossiblePlayerBattleAction::SACRIFICE: newConsoleMsg = CGI->generaltexth->allTexts[543]; //choose army to sacrifice break; case PossiblePlayerBattleAction::FREE_LOCATION: - cursorFrame = ECursor::COMBAT_BLOCKED; + cursorFrame = Cursor::Combat::BLOCKED; newConsoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[181]) % currentSpell->name); //No room to place %s here break; default: if (myNumber == -1) - CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); //set neutral cursor over menu etc. + CCS->curh->set(Cursor::Combat::POINTER); else - cursorFrame = ECursor::COMBAT_BLOCKED; + cursorFrame = Cursor::Combat::BLOCKED; break; } } @@ -600,8 +600,7 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) case PossiblePlayerBattleAction::SACRIFICE: break; default: - cursorType = ECursor::SPELLBOOK; - cursorFrame = 0; + spellcastingCursor = true; if (newConsoleMsg.empty() && currentSpell) newConsoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[26]) % currentSpell->name); //Cast %s break; @@ -662,7 +661,12 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) if (eventType == CIntObject::MOVE) { if (setCursor) - CCS->curh->changeGraphic(cursorType, cursorFrame); + { + if (spellcastingCursor) + CCS->curh->set(Cursor::Spellcast::SPELL); + else + CCS->curh->set(cursorFrame); + } if (!currentConsoleMsg.empty()) owner.controlPanel->console->clearIfMatching(currentConsoleMsg); @@ -680,7 +684,7 @@ void BattleActionsController::handleHex(BattleHex myNumber, int eventType) } realizeAction(); if (!secondaryTarget) //do not replace teleport or sacrifice cursor - CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER); + CCS->curh->set(Cursor::Combat::POINTER); owner.controlPanel->console->clear(); } } diff --git a/client/battle/BattleAnimationClasses.cpp b/client/battle/BattleAnimationClasses.cpp index ad9a84d55..282eb4d2e 100644 --- a/client/battle/BattleAnimationClasses.cpp +++ b/client/battle/BattleAnimationClasses.cpp @@ -417,8 +417,6 @@ MovementAnimation::~MovementAnimation() { assert(stack); - myAnim->pos.moveTo(owner.stacksController->getStackPositionAtHex(nextHex, stack)); - if(owner.moveSoundHander != -1) { CCS->soundh->stopSound(owner.moveSoundHander); @@ -456,6 +454,7 @@ bool MovementEndAnimation::init() } logAnim->debug("CMovementEndAnimation::init: stack %s", stack->getName()); + myAnim->pos.moveTo(owner.stacksController->getStackPositionAtHex(nextHex, stack)); CCS->soundh->playSound(battle_sound(stack->getCreature(), endMoving)); diff --git a/client/battle/BattleControlPanel.cpp b/client/battle/BattleControlPanel.cpp index 21919cb6f..4a1f922e1 100644 --- a/client/battle/BattleControlPanel.cpp +++ b/client/battle/BattleControlPanel.cpp @@ -101,7 +101,7 @@ void BattleControlPanel::bOptionsf() if (owner.actionsController->spellcastingModeActive()) return; - CCS->curh->changeGraphic(ECursor::ADVENTURE,0); + CCS->curh->set(Cursor::Map::POINTER); GH.pushIntT(owner); } @@ -158,7 +158,7 @@ void BattleControlPanel::bFleef() void BattleControlPanel::reallyFlee() { owner.giveCommand(EActionType::RETREAT); - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); } void BattleControlPanel::reallySurrender() @@ -170,7 +170,7 @@ void BattleControlPanel::reallySurrender() else { owner.giveCommand(EActionType::SURRENDER); - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); } } @@ -213,7 +213,7 @@ void BattleControlPanel::bSpellf() if(!myHero) return; - CCS->curh->changeGraphic(ECursor::ADVENTURE,0); + CCS->curh->set(Cursor::Map::POINTER); ESpellCastProblem::ESpellCastProblem spellCastProblem = owner.curInt->cb->battleCanCastSpell(myHero, spells::Mode::HERO); diff --git a/client/battle/BattleFieldController.cpp b/client/battle/BattleFieldController.cpp index d37f230cc..34fea1d87 100644 --- a/client/battle/BattleFieldController.cpp +++ b/client/battle/BattleFieldController.cpp @@ -336,17 +336,17 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) const double subdividingAngle = 2.0*M_PI/6.0; // Divide a hex into six sectors. const double hexMidX = hoveredHexPos.x + hoveredHexPos.w/2.0; const double hexMidY = hoveredHexPos.y + hoveredHexPos.h/2.0; - const double cursorHexAngle = M_PI - atan2(hexMidY - cursor->ypos, cursor->xpos - hexMidX) + subdividingAngle/2; //TODO: refactor this nightmare + const double cursorHexAngle = M_PI - atan2(hexMidY - cursor->position().y, cursor->position().y - hexMidX) + subdividingAngle/2; //TODO: refactor this nightmare const double sector = fmod(cursorHexAngle/subdividingAngle, 6.0); const int zigzagCorrection = !((myNumber/GameConstants::BFIELD_WIDTH)%2); // Off-by-one correction needed to deal with the odd battlefield rows. - std::vector sectorCursor; // From left to bottom left. - sectorCursor.push_back(8); - sectorCursor.push_back(9); - sectorCursor.push_back(10); - sectorCursor.push_back(11); - sectorCursor.push_back(12); - sectorCursor.push_back(7); + std::vector sectorCursor; // From left to bottom left. + sectorCursor.push_back(Cursor::Combat::HIT_EAST); + sectorCursor.push_back(Cursor::Combat::HIT_SOUTHEAST); + sectorCursor.push_back(Cursor::Combat::HIT_SOUTHWEST); + sectorCursor.push_back(Cursor::Combat::HIT_WEST); + sectorCursor.push_back(Cursor::Combat::HIT_NORTHWEST); + sectorCursor.push_back(Cursor::Combat::HIT_NORTHEAST); const bool doubleWide = owner.stacksController->getActiveStack()->doubleWide(); bool aboveAttackable = true, belowAttackable = true; @@ -355,13 +355,13 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) // Check to the left. if (myNumber%GameConstants::BFIELD_WIDTH <= 1 || !vstd::contains(occupyableHexes, myNumber - 1)) { - sectorCursor[0] = -1; + sectorCursor[0] = Cursor::Combat::INVALID; } // Check top left, top right as well as above for 2-hex creatures. if (myNumber/GameConstants::BFIELD_WIDTH == 0) { - sectorCursor[1] = -1; - sectorCursor[2] = -1; + sectorCursor[1] = Cursor::Combat::INVALID; + sectorCursor[2] = Cursor::Combat::INVALID; aboveAttackable = false; } else @@ -380,30 +380,30 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) attackRow[3] = false; if (!(attackRow[0] && attackRow[1])) - sectorCursor[1] = -1; + sectorCursor[1] = Cursor::Combat::INVALID; if (!(attackRow[1] && attackRow[2])) aboveAttackable = false; if (!(attackRow[2] && attackRow[3])) - sectorCursor[2] = -1; + sectorCursor[2] = Cursor::Combat::INVALID; } else { if (!vstd::contains(occupyableHexes, myNumber - GameConstants::BFIELD_WIDTH - 1 + zigzagCorrection)) - sectorCursor[1] = -1; + sectorCursor[1] = Cursor::Combat::INVALID; if (!vstd::contains(occupyableHexes, myNumber - GameConstants::BFIELD_WIDTH + zigzagCorrection)) - sectorCursor[2] = -1; + sectorCursor[2] = Cursor::Combat::INVALID; } } // Check to the right. if (myNumber%GameConstants::BFIELD_WIDTH >= GameConstants::BFIELD_WIDTH - 2 || !vstd::contains(occupyableHexes, myNumber + 1)) { - sectorCursor[3] = -1; + sectorCursor[3] = Cursor::Combat::INVALID; } // Check bottom right, bottom left as well as below for 2-hex creatures. if (myNumber/GameConstants::BFIELD_WIDTH == GameConstants::BFIELD_HEIGHT - 1) { - sectorCursor[4] = -1; - sectorCursor[5] = -1; + sectorCursor[4] = Cursor::Combat::INVALID; + sectorCursor[5] = Cursor::Combat::INVALID; belowAttackable = false; } else @@ -422,18 +422,18 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) attackRow[3] = false; if (!(attackRow[0] && attackRow[1])) - sectorCursor[5] = -1; + sectorCursor[5] = Cursor::Combat::INVALID; if (!(attackRow[1] && attackRow[2])) belowAttackable = false; if (!(attackRow[2] && attackRow[3])) - sectorCursor[4] = -1; + sectorCursor[4] = Cursor::Combat::INVALID; } else { if (!vstd::contains(occupyableHexes, myNumber + GameConstants::BFIELD_WIDTH + zigzagCorrection)) - sectorCursor[4] = -1; + sectorCursor[4] = Cursor::Combat::INVALID; if (!vstd::contains(occupyableHexes, myNumber + GameConstants::BFIELD_WIDTH - 1 + zigzagCorrection)) - sectorCursor[5] = -1; + sectorCursor[5] = Cursor::Combat::INVALID; } } @@ -441,8 +441,8 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) int cursorIndex; if (doubleWide) { - sectorCursor.insert(sectorCursor.begin() + 5, belowAttackable ? 13 : -1); - sectorCursor.insert(sectorCursor.begin() + 2, aboveAttackable ? 14 : -1); + sectorCursor.insert(sectorCursor.begin() + 5, belowAttackable ? Cursor::Combat::HIT_NORTH : Cursor::Combat::INVALID); + sectorCursor.insert(sectorCursor.begin() + 2, aboveAttackable ? Cursor::Combat::HIT_SOUTH : Cursor::Combat::INVALID); if (sector < 1.5) cursorIndex = static_cast(sector); @@ -461,7 +461,7 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) } // Generally should NEVER happen, but to avoid the possibility of having endless loop below... [#1016] - if (!vstd::contains_if (sectorCursor, [](int sc) { return sc != -1; })) + if (!vstd::contains_if (sectorCursor, [](Cursor::Combat sc) { return sc != Cursor::Combat::INVALID; })) { logGlobal->error("Error: for hex %d cannot find a hex to attack from!", myNumber); attackingHex = -1; @@ -471,10 +471,10 @@ void BattleFieldController::setBattleCursor(BattleHex myNumber) // Find the closest direction attackable, starting with the right one. // FIXME: Is this really how the original H3 client does it? int i = 0; - while (sectorCursor[(cursorIndex + i)%sectorCursor.size()] == -1) //Why hast thou forsaken me? + while (sectorCursor[(cursorIndex + i)%sectorCursor.size()] == Cursor::Combat::INVALID) //Why hast thou forsaken me? i = i <= 0 ? 1 - i : -i; // 0, 1, -1, 2, -2, 3, -3 etc.. int index = (cursorIndex + i)%sectorCursor.size(); //hopefully we get elements from sectorCursor - cursor->changeGraphic(ECursor::COMBAT, sectorCursor[index]); + cursor->set(sectorCursor[index]); switch (index) { case 0: @@ -505,9 +505,9 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) { //TODO far too much repeating code BattleHex destHex; - switch(CCS->curh->frame) + switch(CCS->curh->get()) { - case 12: //from bottom right + case Cursor::Combat::HIT_NORTHWEST: //from bottom right { bool doubleWide = owner.stacksController->getActiveStack()->doubleWide(); destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH+1 ) + @@ -526,7 +526,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) } break; } - case 7: //from bottom left + case Cursor::Combat::HIT_NORTHEAST: //from bottom left { destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH-1 : GameConstants::BFIELD_WIDTH ); if (vstd::contains(occupyableHexes, destHex)) @@ -543,7 +543,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) } break; } - case 8: //from left + case Cursor::Combat::HIT_EAST: //from left { if(owner.stacksController->getActiveStack()->doubleWide() && owner.stacksController->getActiveStack()->side == BattleSide::DEFENDER) { @@ -559,7 +559,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) } break; } - case 9: //from top left + case Cursor::Combat::HIT_SOUTHEAST: //from top left { destHex = myNumber - ((myNumber/GameConstants::BFIELD_WIDTH) % 2 ? GameConstants::BFIELD_WIDTH + 1 : GameConstants::BFIELD_WIDTH); if(vstd::contains(occupyableHexes, destHex)) @@ -576,7 +576,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) } break; } - case 10: //from top right + case Cursor::Combat::HIT_SOUTHWEST: //from top right { bool doubleWide = owner.stacksController->getActiveStack()->doubleWide(); destHex = myNumber - ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH-1 ) + @@ -595,7 +595,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) } break; } - case 11: //from right + case Cursor::Combat::HIT_WEST: //from right { if(owner.stacksController->getActiveStack()->doubleWide() && owner.stacksController->getActiveStack()->side == BattleSide::ATTACKER) { @@ -611,7 +611,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) } break; } - case 13: //from bottom + case Cursor::Combat::HIT_NORTH: //from bottom { destHex = myNumber + ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH+1 ); if(vstd::contains(occupyableHexes, destHex)) @@ -628,7 +628,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) } break; } - case 14: //from top + case Cursor::Combat::HIT_SOUTH: //from top { destHex = myNumber - ( (myNumber/GameConstants::BFIELD_WIDTH)%2 ? GameConstants::BFIELD_WIDTH : GameConstants::BFIELD_WIDTH-1 ); if (vstd::contains(occupyableHexes, destHex)) @@ -646,7 +646,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex myNumber) break; } } - return -1; + return BattleHex::INVALID; } bool BattleFieldController::isTileAttackable(const BattleHex & number) const diff --git a/client/battle/BattleInterface.cpp b/client/battle/BattleInterface.cpp index 413b75308..27986d88c 100644 --- a/client/battle/BattleInterface.cpp +++ b/client/battle/BattleInterface.cpp @@ -470,7 +470,7 @@ void BattleInterface::battleFinished(const BattleResult& br) void BattleInterface::displayBattleFinished() { - CCS->curh->changeGraphic(ECursor::ADVENTURE,0); + CCS->curh->set(Cursor::Map::POINTER); if(settings["session"]["spectate"].Bool() && settings["session"]["spectate-skip-battle-result"].Bool()) { close(); diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 0db0968d4..1c6c92ad8 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -221,9 +221,9 @@ void BattleHero::hover(bool on) { //TODO: BROKEN CODE if (on) - CCS->curh->changeGraphic(ECursor::COMBAT, 5); + CCS->curh->set(Cursor::Combat::HERO); else - CCS->curh->changeGraphic(ECursor::COMBAT, 0); + CCS->curh->set(Cursor::Combat::POINTER); } void BattleHero::clickLeft(tribool down, bool previousState) @@ -244,7 +244,7 @@ void BattleHero::clickLeft(tribool down, bool previousState) if ( hoveredHex != BattleHex::INVALID ) return; - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); GH.pushIntT(myHero, owner.getCurrentPlayerInterface()); } diff --git a/client/battle/BattleStacksController.cpp b/client/battle/BattleStacksController.cpp index dc7e27342..573b5a4d4 100644 --- a/client/battle/BattleStacksController.cpp +++ b/client/battle/BattleStacksController.cpp @@ -504,7 +504,7 @@ void BattleStacksController::stackMoved(const CStack *stack, std::vectorhasBonus(Selector::typeSubtype(Bonus::FLYING, 1)) ) + if (!stack->hasBonus(Selector::typeSubtype(Bonus::FLYING, 1)) ) { addNewAnim(new MovementAnimation(owner, stack, destHex, distance)); owner.waitForAnimationCondition(EAnimationEvents::ACTION, false); diff --git a/client/gui/CCursorHandler.cpp b/client/gui/CCursorHandler.cpp index 43e5999ad..6fc10ef75 100644 --- a/client/gui/CCursorHandler.cpp +++ b/client/gui/CCursorHandler.cpp @@ -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("CRSPELL", 0) }; - currentCursor = cursors.at(int(ECursor::DEFAULT)).get(); + currentCursor = cursors.at(static_cast(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(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(index)); +} + +void CCursorHandler::set(Cursor::Map index) +{ + changeGraphic(Cursor::Type::ADVENTURE, static_cast(index)); +} + +void CCursorHandler::set(Cursor::Combat index) +{ + changeGraphic(Cursor::Type::COMBAT, static_cast(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 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(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(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(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) diff --git a/client/gui/CCursorHandler.h b/client/gui/CCursorHandler.h index cfbc1e290..82082a93d 100644 --- a/client/gui/CCursorHandler.h +++ b/client/gui/CCursorHandler.h @@ -12,89 +12,96 @@ class CIntObject; class CAnimImage; struct SDL_Surface; struct SDL_Texture; +struct Point; -namespace ECursor +namespace Cursor { - enum ECursorTypes { + enum class Type { ADVENTURE, // set of various cursors for adventure map COMBAT, // set of various cursors for combat DEFAULT, // default arrow and hourglass cursors SPELLBOOK // animated cursor for spellcasting }; - enum EDefaultCursors { - DEFAULT_ARROW = 0, - DEFAULT_ARROW_COPY = 1, // probably unused - DEFAULT_HOURGLASS = 2, + enum class Default { + POINTER = 0, + //ARROW_COPY = 1, // probably unused + HOURGLASS = 2, }; - enum EBattleCursors { - COMBAT_BLOCKED = 0, - COMBAT_MOVE = 1, - COMBAT_FLY = 2, - COMBAT_SHOOT = 3, - COMBAT_HERO = 4, - COMBAT_QUERY = 5, - COMBAT_POINTER = 6, - COMBAT_HIT_NORTHEAST = 7, - COMBAT_HIT_EAST = 8, - COMBAT_HIT_SOUTHEAST = 9, - COMBAT_HIT_SOUTHWEST = 10, - COMBAT_HIT_WEST = 11, - COMBAT_HIT_NORTHWEST = 12, - COMBAT_HIT_NORTH = 13, - COMBAT_HIT_SOUTH = 14, - COMBAT_SHOOT_PENALTY = 15, - COMBAT_SHOOT_CATAPULT = 16, - COMBAT_HEAL = 17, - COMBAT_SACRIFICE = 18, - COMBAT_TELEPORT = 19 + enum class Combat { + INVALID = -1, + + BLOCKED = 0, + MOVE = 1, + FLY = 2, + SHOOT = 3, + HERO = 4, + QUERY = 5, + POINTER = 6, + HIT_NORTHEAST = 7, + HIT_EAST = 8, + HIT_SOUTHEAST = 9, + HIT_SOUTHWEST = 10, + HIT_WEST = 11, + HIT_NORTHWEST = 12, + HIT_NORTH = 13, + HIT_SOUTH = 14, + SHOOT_PENALTY = 15, + SHOOT_CATAPULT = 16, + HEAL = 17, + SACRIFICE = 18, + TELEPORT = 19 }; - enum EAdventureCursors { - ADV_ARROW = 0, - ADV_HOURGLASS = 1, - ADV_HERO = 2, - ADV_TOWN = 3, - ADV_T1_MOVE = 4, - ADV_T1_ATTACK = 5, - ADV_T1_SAIL = 6, - ADV_T1_DISEMBARK = 7, - ADV_T1_EXCHANGE = 8, - ADV_T1_VISIT = 9, - ADV_T2_MOVE = 10, - ADV_T2_ATTACK = 11, - ADV_T2_SAIL = 12, - ADV_T2_DISEMBARK = 13, - ADV_T2_EXCHANGE = 14, - ADV_T2_VISIT = 15, - ADV_T3_MOVE = 16, - ADV_T3_ATTACK = 17, - ADV_T3_SAIL = 18, - ADV_T3_DISEMBARK = 19, - ADV_T3_EXCHANGE = 20, - ADV_T3_VISIT = 21, - ADV_T4_MOVE = 22, - ADV_T4_ATTACK = 23, - ADV_T4_SAIL = 24, - ADV_T4_DISEMBARK = 25, - ADV_T4_EXCHANGE = 26, - ADV_T4_VISIT = 27, - ADV_T1_SAIL_VISIT = 28, - ADV_T2_SAIL_VISIT = 29, - ADV_T3_SAIL_VISIT = 30, - ADV_T4_SAIL_VISIT = 31, - ADV_SCROLL_NORTH = 32, - ADV_SCROLL_NORTHEAST = 33, - ADV_SCROLL_EAST = 34, - ADV_SCROLL_SOUTHEAST = 35, - ADV_SCROLL_SOUTH = 36, - ADV_SCROLL_SOUTHWEST = 37, - ADV_SCROLL_WEST = 38, - ADV_SCROLL_NORTHWEST = 39, - ADV_ARROW_COPY = 40, // probably unused - ADV_TELEPORT = 41, - ADV_SCUTTLE_SHIP = 42 + enum class Map { + POINTER = 0, + HOURGLASS = 1, + HERO = 2, + TOWN = 3, + T1_MOVE = 4, + T1_ATTACK = 5, + T1_SAIL = 6, + T1_DISEMBARK = 7, + T1_EXCHANGE = 8, + T1_VISIT = 9, + T2_MOVE = 10, + T2_ATTACK = 11, + T2_SAIL = 12, + T2_DISEMBARK = 13, + T2_EXCHANGE = 14, + T2_VISIT = 15, + T3_MOVE = 16, + T3_ATTACK = 17, + T3_SAIL = 18, + T3_DISEMBARK = 19, + T3_EXCHANGE = 20, + T3_VISIT = 21, + T4_MOVE = 22, + T4_ATTACK = 23, + T4_SAIL = 24, + T4_DISEMBARK = 25, + T4_EXCHANGE = 26, + T4_VISIT = 27, + T1_SAIL_VISIT = 28, + T2_SAIL_VISIT = 29, + T3_SAIL_VISIT = 30, + T4_SAIL_VISIT = 31, + SCROLL_NORTH = 32, + SCROLL_NORTHEAST = 33, + SCROLL_EAST = 34, + SCROLL_SOUTHEAST = 35, + SCROLL_SOUTH = 36, + SCROLL_SOUTHWEST = 37, + SCROLL_WEST = 38, + SCROLL_NORTHWEST = 39, + //POINTER_COPY = 40, // probably unused + TELEPORT = 41, + SCUTTLE_BOAT = 42 + }; + + enum class Spellcast { + SPELL = 0, }; } @@ -119,19 +126,20 @@ class CCursorHandler final void shiftPos( int &x, int &y ); void updateTexture(); -public: + + /// Current cursor + Cursor::Type type; + size_t frame; + float frameTime; + + void changeGraphic(Cursor::Type type, size_t index); + /// position of cursor int xpos, ypos; - /// Current cursor - ECursor::ECursorTypes type; - size_t frame; - - /// inits cursorHandler - run only once, it's not memleak-proof (rev 1333) - void initCursor(); - - /// changes cursor graphic for type type (0 - adventure, 1 - combat, 2 - default, 3 - spellbook) and frame index (not used for type 3) - void changeGraphic(ECursor::ECursorTypes type, int index); +public: + CCursorHandler(); + ~CCursorHandler(); /** * Replaces the cursor with a custom image. @@ -141,6 +149,27 @@ public: */ void dragAndDropCursor (std::unique_ptr image); + /// Returns current position of the cursor + Point position() const; + + /// Changes cursor to specified index + void set(Cursor::Default index); + void set(Cursor::Map index); + void set(Cursor::Combat index); + void set(Cursor::Spellcast index); + + /// Returns current index of cursor + template + Index get() + { + assert((std::is_same::value )|| type != Cursor::Type::DEFAULT ); + assert((std::is_same::value )|| type != Cursor::Type::ADVENTURE ); + assert((std::is_same::value )|| type != Cursor::Type::COMBAT ); + assert((std::is_same::value )|| type != Cursor::Type::SPELLBOOK ); + + return static_cast(frame); + } + void render(); void hide() { showing=false; }; @@ -151,6 +180,4 @@ public: /// Move cursor to screen center void centerCursor(); - CCursorHandler(); - ~CCursorHandler(); }; diff --git a/client/gui/CGuiHandler.cpp b/client/gui/CGuiHandler.cpp index 27e5508b8..32a79e736 100644 --- a/client/gui/CGuiHandler.cpp +++ b/client/gui/CGuiHandler.cpp @@ -121,7 +121,7 @@ void CGuiHandler::pushInt(std::shared_ptr newInt) if(!listInt.empty()) listInt.front()->deactivate(); listInt.push_front(newInt); - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); newInt->activate(); objsToBlit.push_back(newInt); totalRedraw(); diff --git a/client/windows/CAdvmapInterface.cpp b/client/windows/CAdvmapInterface.cpp index 8d0e500e8..c8dd453d7 100644 --- a/client/windows/CAdvmapInterface.cpp +++ b/client/windows/CAdvmapInterface.cpp @@ -68,25 +68,25 @@ static void setScrollingCursor(ui8 direction) if(direction & CAdvMapInt::RIGHT) { if(direction & CAdvMapInt::UP) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 33); + CCS->curh->set(Cursor::Map::SCROLL_NORTHEAST); else if(direction & CAdvMapInt::DOWN) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 35); + CCS->curh->set(Cursor::Map::SCROLL_SOUTHEAST); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 34); + CCS->curh->set(Cursor::Map::SCROLL_EAST); } else if(direction & CAdvMapInt::LEFT) { if(direction & CAdvMapInt::UP) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 39); + CCS->curh->set(Cursor::Map::SCROLL_NORTHWEST); else if(direction & CAdvMapInt::DOWN) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 37); + CCS->curh->set(Cursor::Map::SCROLL_SOUTHWEST); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 38); + CCS->curh->set(Cursor::Map::SCROLL_WEST); } else if(direction & CAdvMapInt::UP) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 32); + CCS->curh->set(Cursor::Map::SCROLL_NORTH); else if(direction & CAdvMapInt::DOWN) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 36); + CCS->curh->set(Cursor::Map::SCROLL_SOUTH); } CTerrainRect::CTerrainRect() @@ -231,7 +231,7 @@ void CTerrainRect::handleHover(const SDL_MouseMotionEvent &sEvent) if(tHovered != pom) //tile outside the map { - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); return; } @@ -247,7 +247,7 @@ void CTerrainRect::hover(bool on) if (!on) { adventureInt->statusbar->clear(); - CCS->curh->changeGraphic(ECursor::ADVENTURE,0); + CCS->curh->set(Cursor::Map::POINTER); } //Hoverable::hover(on); } @@ -968,7 +968,7 @@ void CAdvMapInt::deactivate() { scrollingDir = 0; - CCS->curh->changeGraphic(ECursor::ADVENTURE,0); + CCS->curh->set(Cursor::Map::POINTER); activeMapPanel->deactivate(); if (mode == EAdvMapMode::NORMAL) { @@ -1125,7 +1125,7 @@ void CAdvMapInt::handleMapScrollingUpdate() } else if(scrollingState) { - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); scrollingState = false; } } @@ -1138,7 +1138,7 @@ void CAdvMapInt::handleSwipeUpdate() auto fixedPos = LOCPLINT->repairScreenPos(swipeTargetPosition); position.x = fixedPos.x; position.y = fixedPos.y; - CCS->curh->changeGraphic(ECursor::DEFAULT, 0); + CCS->curh->set(Cursor::Map::POINTER); updateScreen = true; minimap.redraw(); swipeMovementRequested = false; @@ -1656,7 +1656,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) return; if(!LOCPLINT->cb->isVisible(mapPos)) { - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); statusbar->clear(); return; } @@ -1682,18 +1682,18 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) { case SpellID::SCUTTLE_BOAT: if(objAtTile && objAtTile->ID == Obj::BOAT) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 42); + CCS->curh->set(Cursor::Map::SCUTTLE_BOAT); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); return; case SpellID::DIMENSION_DOOR: { const TerrainTile * t = LOCPLINT->cb->getTile(mapPos, false); int3 hpos = selection->getSightCenter(); if((!t || t->isClear(LOCPLINT->cb->getTile(hpos))) && isInScreenRange(hpos, mapPos)) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 41); + CCS->curh->set(Cursor::Map::TELEPORT); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); return; } } @@ -1704,17 +1704,25 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) if(objAtTile) { if(objAtTile->ID == Obj::TOWN && objRelations != PlayerRelations::ENEMIES) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 3); + CCS->curh->set(Cursor::Map::TOWN); else if(objAtTile->ID == Obj::HERO && objRelations == PlayerRelations::SAME_PLAYER) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 2); + CCS->curh->set(Cursor::Map::HERO); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); } else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); } else if(const CGHeroInstance * h = curHero()) { + std::array cursorMove = { Cursor::Map::T1_MOVE, Cursor::Map::T2_MOVE, Cursor::Map::T3_MOVE, Cursor::Map::T4_MOVE, }; + std::array cursorAttack = { Cursor::Map::T1_ATTACK, Cursor::Map::T2_ATTACK, Cursor::Map::T3_ATTACK, Cursor::Map::T4_ATTACK, }; + std::array cursorSail = { Cursor::Map::T1_SAIL, Cursor::Map::T2_SAIL, Cursor::Map::T3_SAIL, Cursor::Map::T4_SAIL, }; + std::array cursorDisembark = { Cursor::Map::T1_DISEMBARK, Cursor::Map::T2_DISEMBARK, Cursor::Map::T3_DISEMBARK, Cursor::Map::T4_DISEMBARK, }; + std::array cursorExchange = { Cursor::Map::T1_EXCHANGE, Cursor::Map::T2_EXCHANGE, Cursor::Map::T3_EXCHANGE, Cursor::Map::T4_EXCHANGE, }; + std::array cursorVisit = { Cursor::Map::T1_VISIT, Cursor::Map::T2_VISIT, Cursor::Map::T3_VISIT, Cursor::Map::T4_VISIT, }; + std::array cursorSailVisit = { Cursor::Map::T1_SAIL_VISIT, Cursor::Map::T2_SAIL_VISIT, Cursor::Map::T3_SAIL_VISIT, Cursor::Map::T4_SAIL_VISIT, }; + const CGPathNode * pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPos); assert(pnode); @@ -1725,9 +1733,9 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) case CGPathNode::NORMAL: case CGPathNode::TELEPORT_NORMAL: if(pnode->layer == EPathfindingLayer::LAND) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 4 + turns*6); + CCS->curh->set(cursorMove[turns]); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 28 + turns); + CCS->curh->set(cursorSailVisit[turns]); break; case CGPathNode::VISIT: @@ -1736,48 +1744,48 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) if(objAtTile && objAtTile->ID == Obj::HERO) { if(selection == objAtTile) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 2); + CCS->curh->set(Cursor::Map::HERO); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 8 + turns*6); + CCS->curh->set(cursorExchange[turns]); } else if(pnode->layer == EPathfindingLayer::LAND) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 9 + turns*6); + CCS->curh->set(cursorVisit[turns]); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 28 + turns); + CCS->curh->set(cursorSailVisit[turns]); break; case CGPathNode::BATTLE: case CGPathNode::TELEPORT_BATTLE: - CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6); + CCS->curh->set(cursorAttack[turns]); break; case CGPathNode::EMBARK: - CCS->curh->changeGraphic(ECursor::ADVENTURE, 6 + turns*6); + CCS->curh->set(cursorSail[turns]); break; case CGPathNode::DISEMBARK: - CCS->curh->changeGraphic(ECursor::ADVENTURE, 7 + turns*6); + CCS->curh->set(cursorDisembark[turns]); break; default: if(objAtTile && objRelations != PlayerRelations::ENEMIES) { if(objAtTile->ID == Obj::TOWN) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 3); + CCS->curh->set(Cursor::Map::TOWN); else if(objAtTile->ID == Obj::HERO && objRelations == PlayerRelations::SAME_PLAYER) - CCS->curh->changeGraphic(ECursor::ADVENTURE, 2); + CCS->curh->set(Cursor::Map::HERO); else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); } else - CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); + CCS->curh->set(Cursor::Map::POINTER); break; } } if(ourInaccessibleShipyard(objAtTile)) { - CCS->curh->changeGraphic(ECursor::ADVENTURE, 6); + CCS->curh->set(Cursor::Map::T1_SAIL); } } @@ -1857,7 +1865,9 @@ const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *ob { const IShipyard *ret = IShipyard::castFrom(obj); - if(!ret || obj->tempOwner != player || CCS->curh->type || (CCS->curh->frame != 6 && CCS->curh->frame != 0)) + if(!ret || + obj->tempOwner != player || + (CCS->curh->get() != Cursor::Map::T1_SAIL && CCS->curh->get() != Cursor::Map::POINTER)) return nullptr; return ret;