mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Merge remote-tracking branch 'origin/develop' into settings-rework
This commit is contained in:
commit
fc7d2b9778
@ -173,6 +173,18 @@ set(CMAKE_XCODE_ATTRIBUTE_MARKETING_VERSION ${APP_SHORT_VERSION})
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH NO)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH[variant=Debug] YES)
|
||||
|
||||
#Check for endian
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.20.0")
|
||||
include(TestBigEndian)
|
||||
test_big_endian(VCMI_ENDIAN_BIG)
|
||||
if(VCMI_ENDIAN_BIG)
|
||||
add_definitions(-DVCMI_ENDIAN_BIG)
|
||||
endif()
|
||||
elseif(${CMAKE_CXX_BYTE_ORDER} EQUAL "BIG_ENDIAN")
|
||||
add_definitions(-DVCMI_ENDIAN_BIG)
|
||||
endif()
|
||||
|
||||
|
||||
if(ENABLE_LAUNCHER)
|
||||
add_definitions(-DENABLE_LAUNCHER)
|
||||
endif()
|
||||
|
157
ChangeLog.md
157
ChangeLog.md
@ -1,3 +1,160 @@
|
||||
# 1.1.1 -> 1.2.0
|
||||
(unreleased, changes for 1.1.1..9c59025)
|
||||
|
||||
### GENERAL:
|
||||
* Implemented hardware cursor support
|
||||
* Heroes III language can now be detected automatically
|
||||
* Increased targeted framerate from 48 to 60
|
||||
* Fixed bonus values of heroes who specialize in secondary skills
|
||||
* Fixed bonus values of heroes who specialize in creatures
|
||||
* Fixed damage increase from Adela's Bless specialty
|
||||
* Fixed missing obstacles in battles on subterranean terrain
|
||||
* Added vcmifaerie, vcmiazure, vcmiarmy, vcmiexp cheats
|
||||
* Video files now play at correct speed
|
||||
|
||||
### MAP EDITOR:
|
||||
* Added translations to German, Polish, Russian, Ukrainian
|
||||
* Implemented cut/copy/paste operations
|
||||
* Implemented lasso brush for terrain editing
|
||||
|
||||
### LAUNCHER:
|
||||
* Icons now have higher resolution, to prevent upscaling artifacts
|
||||
* Added translations to German, Polish, Russian, Ukrainian
|
||||
* Mods tab layout has been adjusted based on feedback from players
|
||||
* Settings tab layout has been redesigned to support longer texts
|
||||
* Added button to start map editor directly from Launcher
|
||||
|
||||
### ADVENTURE MAP:
|
||||
* Implemented different hero movement sounds for offroad movement
|
||||
* Cartographers now reveal terrain in the same way as in H3
|
||||
* Holding ALT will now show movement points information in status bar
|
||||
* It is now not possible to receive rewards from School of War without required gold amount
|
||||
* Owned objects, like Mines and Dwellings will always show their owner in status bar
|
||||
* It is now possible to interact with on-map Shipyard when no hero is selected
|
||||
|
||||
## INTERFACE
|
||||
* Fixed white status bar on server connection screen
|
||||
* Buttons in battle window now correctly show tooltip in status bar
|
||||
* Fixed cursor image during enemy turn in combat
|
||||
* Fixed cases of incorrect artifact slot highlighting
|
||||
* Game will no longer promt to assemble artifacts if they fall into backpack
|
||||
* It is now possible to use in-game console for vcmi commands
|
||||
* Stacks sized 1000-9999 units will not be displayed as "1k"
|
||||
* It is now possible to select destination town for Town Portal via double-click
|
||||
|
||||
### TOWN SCREEN
|
||||
* Fixed gradual fade-in of a newly built building
|
||||
* Fixed duration of building fade-in to match H3
|
||||
* Fixed rendering of Shipyard in Castle
|
||||
|
||||
### BATTLES:
|
||||
* All effects will now wait for battle opening sound before playing
|
||||
* Hex highlighting will now be disabled during enemy turn
|
||||
* Fixed incorrect log message when casting spell that kills zero units
|
||||
* Implemented animated cursor for spellcasting
|
||||
* Fixed multiple issues related to ordering of creature animations
|
||||
* Fixed missing flags from hero animations when opening menus
|
||||
* Fixed rendering order of moat and grid shadow
|
||||
* Jousting bonus from Champions will now be correctly accounted for in damage estimation
|
||||
* Building Castle building will now provide walls with additional health point
|
||||
* Speed of all battle animations should now match H3
|
||||
* Fixed missing obstacles on subterranean terrain
|
||||
* Ballistics mechanics now matches H3 logic
|
||||
* Arrow Tower base damage should now match H3
|
||||
* Destruction of wall segments will now remove ranged attack penalty
|
||||
* Force Field cast in front of drawbridge will now block it as in H3
|
||||
* Fixed computations for Behemoth defense reduction ability
|
||||
* Bad luck (if enabled) will now multiple all damage by 50%, in line with other damage reducing mechanics
|
||||
* Fixed highlighting of movement range for creatures standing on a corpse
|
||||
* All battle animations now have same duration/speed as in H3
|
||||
* Added missing combat log message on resurrecting creatures
|
||||
* Fixed visibility of blue border around targeted creature when spellcaster is making turn
|
||||
* Fixed selection highlight when in targeted creature spellcasting mode
|
||||
* Hovering over hero now correctly shows hero cursor
|
||||
* Creature currently making turn is now highlighted in the Battle Queue
|
||||
* Hovering over creature icon in Battle Queue will highlight this creature in the battlefield
|
||||
|
||||
### SPELLS:
|
||||
* Hero casting animation will play before spell effect
|
||||
* Fire Shield: added sound effect
|
||||
* Fire Shield: effect now correctly plays on defending creature
|
||||
* Earthquake: added sound effect
|
||||
* Earthquake: spell will not select sections that were already destroyed before cast
|
||||
* Remove Obstacles: fixed error message when casting on maps without obstacles
|
||||
* All area-effect spells (e.g. Fireball) will play their effect animation on top
|
||||
* Summoning spells: added fade-in effect for summoned creatures
|
||||
* Fixed timing of hit animation for damage-dealing spells
|
||||
* Obstacle-creating spells: UI is now locked during effect animation
|
||||
* Obstacle-creating spells: added sound effect
|
||||
* Added reverse death animation for spells that bring stack back to life
|
||||
* Bloodlust: implemented visual effect
|
||||
* Teleport: implemented visual fade-out and fade-in effect for teleporting
|
||||
* Berserk: Fixed duration of effect
|
||||
* Frost Ring: Fixed spell effect range
|
||||
* Fixed several cases where multiple different effects could play at the same time
|
||||
* All spells that can affecte multiple targets will now highlight affected stacks
|
||||
* Bless and Curse now provide +1 or -1 to base damage on Advanced & Expert levels
|
||||
|
||||
### ABILITIES:
|
||||
* Rebirth (Phoenix): Sound will now play in the same time as animation effect
|
||||
* Master Genie spellcasting: Sound will now play in the same time as animation effect
|
||||
* Power Lich, Magogs: Sound will now play in the same time as attack animation effect
|
||||
* Dragon Breath attack now correctly uses different attack animation if multiple targets are hit
|
||||
* Petrification: implemented visual effect
|
||||
* Paralyze: added visual effect
|
||||
* Blind: Stacks will no longer retailate on attack that blinds them
|
||||
* Demon Summon: Added animation effect for summoning
|
||||
* Fire shield will no longer trigger on non-adjacent attacks, e.g. from Dragon Breath
|
||||
* Weakness now has correct visual effect
|
||||
* Added damage bonus for opposite elements for Elementals
|
||||
* Added damage reduction for Magic Elemental attacks against creatures immune to magic
|
||||
* Added incoming damage reduction to Petrify
|
||||
* Added counter-attack damage reduction for Paralyze
|
||||
|
||||
### MODDING:
|
||||
* All configurable objects from H3 now have their configuration in json
|
||||
* Improvements to functionality of configurable objects
|
||||
* It is now possible to define new hero movement sounds in terrains
|
||||
* Implemented translation support for mods
|
||||
* Files with new Terrains, Roads and Rivers are now validated by game
|
||||
* Parameters controlling effect of attack and defences stats on damage are now configurable in defaultMods.json
|
||||
* New bonus: LIMITED_SHOOTING_RANGE. Creatures with this bonus can only use ranged attack within specified range
|
||||
* Battle window and Random Map Tab now have their layout defined in json file
|
||||
* Implemented code support for alternative actions mod
|
||||
* Implemented code support for improved random map dialog
|
||||
|
||||
# 1.1.0 -> 1.1.1
|
||||
|
||||
### GENERAL:
|
||||
* Fixed missing sound in Polish version from gog.com
|
||||
* Fixed positioning of main menu buttons in localized versions of H3
|
||||
* Fixed crash on transferring artifact to commander
|
||||
* Fixed game freeze on receiving multiple artifact assembly dialogs after combat
|
||||
* Fixed potential game freeze on end of music playback
|
||||
* macOS/iOS: fixed sound glitches
|
||||
* Android: upgraded version of SDL library
|
||||
* Android: reworked right click gesture and relative pointer mode
|
||||
* Improved map loading speed
|
||||
* Ubuntu PPA: game will no longer crash on assertion failure
|
||||
|
||||
### ADVENTURE MAP:
|
||||
* Fixed hero movement lag in single-player games
|
||||
* Fixed number of drowned troops on visiting Sirens to match H3
|
||||
* iOS: pinch gesture visits current object (Spacebar behavior) instead of activating in-game console
|
||||
|
||||
### TOWNS:
|
||||
* Fixed displaying growth bonus from Statue of Legion
|
||||
* Growth bonus tooltip ordering now matches H3
|
||||
* Buy All Units dialog will now buy units starting from the highest level
|
||||
|
||||
### LAUNCHER:
|
||||
* Local mods can be disabled or uninstalled
|
||||
* Fixed styling of Launcher interface
|
||||
|
||||
### MAP EDITOR:
|
||||
* Fixed saving of roads and rivers
|
||||
* Fixed placement of heroes on map
|
||||
|
||||
# 1.0.0 -> 1.1.0
|
||||
|
||||
### GENERAL:
|
||||
|
22
Global.h
22
Global.h
@ -725,7 +725,27 @@ namespace vstd
|
||||
return a + (b - a) * f;
|
||||
}
|
||||
|
||||
using boost::math::round;
|
||||
/// converts number into string using metric system prefixes, e.g. 'k' or 'M' to keep resulting strings within specified size
|
||||
/// Note that resulting string may have more symbols than digits: minus sign and prefix symbol
|
||||
template<typename Arithmetic>
|
||||
std::string formatMetric(Arithmetic number, int maxDigits)
|
||||
{
|
||||
Arithmetic max = std::pow(10, maxDigits);
|
||||
if (std::abs(number) < max)
|
||||
return std::to_string(number);
|
||||
|
||||
std::string symbols = " kMGTPE";
|
||||
auto iter = symbols.begin();
|
||||
|
||||
while (std::abs(number) >= max)
|
||||
{
|
||||
number /= 1000;
|
||||
iter++;
|
||||
|
||||
assert(iter != symbols.end());//should be enough even for int64
|
||||
}
|
||||
return std::to_string(number) + *iter;
|
||||
}
|
||||
}
|
||||
using vstd::operator-=;
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.name": "Attack all around",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.description": "Attacks all adjacent enemies",
|
||||
"core.bonus.BLOCKS_RETALIATION.name": "No retaliation",
|
||||
"core.bonus.BLOCKS_RETALIATION.description": "Enemy cannot Retaliate",
|
||||
"core.bonus.BLOCKS_RETALIATION.description": "Enemy cannot retaliate",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.name": "No ranged retaliation",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.description": "Enemy cannot Retaliate by shooting",
|
||||
"core.bonus.CATAPULT.name": "Catapult",
|
||||
@ -143,7 +143,7 @@
|
||||
"core.bonus.FREE_SHOOTING.name": "Shoot Close",
|
||||
"core.bonus.FREE_SHOOTING.description": "Can shoot in Close Combat",
|
||||
"core.bonus.FULL_HP_REGENERATION.name": "Regeneration",
|
||||
"core.bonus.FULL_HP_REGENERATION.description": "May Regenerate to full Health",
|
||||
"core.bonus.FULL_HP_REGENERATION.description": "May regenerate to full health",
|
||||
"core.bonus.GARGOYLE.name": "Gargoyle",
|
||||
"core.bonus.GARGOYLE.description": "Cannot be rised or healed",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.name": "Reduce Damage (${val}%)",
|
||||
@ -165,7 +165,7 @@
|
||||
"core.bonus.LEVEL_SPELL_IMMUNITY.name": "Spell immunity 1-${val}",
|
||||
"core.bonus.LEVEL_SPELL_IMMUNITY.description": "Immune to spells of levels 1-${val}",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.name" : "Limited shooting range",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.description" : "",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.description" : "Cannot shoot targets beyond ${val} hexes away",
|
||||
"core.bonus.LIFE_DRAIN.name": "Drain life (${val}%)",
|
||||
"core.bonus.LIFE_DRAIN.description": "Drains ${val}% of damage dealt",
|
||||
"core.bonus.MANA_CHANNELING.name": "Magic Channel ${val}%",
|
||||
@ -221,7 +221,7 @@
|
||||
"core.bonus.SPELL_LIKE_ATTACK.name": "Spell-like attack",
|
||||
"core.bonus.SPELL_LIKE_ATTACK.description": "Attacks with ${subtype.spell}",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.name": "Aura of Resistance",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.description": "Nearby stacks get ${val}% resistance",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.description": "Nearby stacks get ${val}% magic resistance",
|
||||
"core.bonus.SUMMON_GUARDIANS.name": "Summon guardians",
|
||||
"core.bonus.SUMMON_GUARDIANS.description": "At battle start summons ${subtype.creature} (${val}%)",
|
||||
"core.bonus.SYNERGY_TARGET.name": "Synergizable",
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"vcmi.adventureMap.monsterThreat.title" : "\n\n Poziom zagrożenia: ",
|
||||
"vcmi.adventureMap.monsterThreat.title" : "\n\n Zagrożenie: ",
|
||||
"vcmi.adventureMap.monsterThreat.levels.0" : "Zerowy",
|
||||
"vcmi.adventureMap.monsterThreat.levels.1" : "Bardzo słaby",
|
||||
"vcmi.adventureMap.monsterThreat.levels.2" : "Słaby",
|
||||
@ -13,11 +13,13 @@
|
||||
"vcmi.adventureMap.monsterThreat.levels.10" : "Śmiertelny",
|
||||
"vcmi.adventureMap.monsterThreat.levels.11" : "Nie do pokonania",
|
||||
|
||||
"vcmi.adventureMap.confirmRestartGame" : "Czy na pewno chcesz zrestartować grę?",
|
||||
"vcmi.adventureMap.noTownWithMarket" : "Brak dostępnego targowiska!",
|
||||
"vcmi.adventureMap.noTownWithTavern" : "Brak dostępnego miasta z karczmą!",
|
||||
"vcmi.adventureMap.spellUnknownProblem" : "Nieznany problem z zaklęciem, brak dodatkowych informacji.",
|
||||
"vcmi.adventureMap.playerAttacked" : "Gracz został zaatakowany: %s",
|
||||
"vcmi.adventureMap.confirmRestartGame" : "Czy na pewno chcesz zrestartować grę?",
|
||||
"vcmi.adventureMap.noTownWithMarket" : "Brak dostępnego targowiska!",
|
||||
"vcmi.adventureMap.noTownWithTavern" : "Brak dostępnego miasta z karczmą!",
|
||||
"vcmi.adventureMap.spellUnknownProblem" : "Nieznany problem z zaklęciem, brak dodatkowych informacji.",
|
||||
"vcmi.adventureMap.playerAttacked" : "Gracz został zaatakowany: %s",
|
||||
"vcmi.adventureMap.moveCostDetails" : "Punkty ruchu - Koszt: %TURNS tury + %POINTS punkty, Pozostałe punkty: %REMAINING",
|
||||
"vcmi.adventureMap.moveCostDetailsNoTurns" : "Punkty ruchu - Koszt: %POINTS punkty, Pozostałe punkty: %REMAINING",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Inny proces vcmiserver został już uruchomiony, zakończ go nim przejdziesz dalej",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Mody wymagane do wczytania gry:",
|
||||
@ -66,5 +68,162 @@
|
||||
"vcmi.randomMapTab.widgets.defaultTemplate" : "domyślny",
|
||||
"vcmi.randomMapTab.widgets.templateLabel" : "Szablon",
|
||||
"vcmi.randomMapTab.widgets.teamAlignmentsButton" : "Ustaw...",
|
||||
"vcmi.randomMapTab.widgets.teamAlignmentsLabel" : "Sojusze"
|
||||
"vcmi.randomMapTab.widgets.teamAlignmentsLabel" : "Sojusze",
|
||||
|
||||
"core.bonus.ADDITIONAL_ATTACK.name": "Podwójne Uderzenie",
|
||||
"core.bonus.ADDITIONAL_ATTACK.description": "Atakuje podwójnie",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.name": "Dodatkowe kontrataki",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.description": "Może kontratakować ${val} dodatkowych razy",
|
||||
"core.bonus.AIR_IMMUNITY.name": "Odporność na powietrze",
|
||||
"core.bonus.AIR_IMMUNITY.description": "Odporny na wszystkie czary szkoły powietrza",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.name": "Atakuje wszystko dookoła",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.description": "Atakuje wszystkich sąsiadujących wrogów",
|
||||
"core.bonus.BLOCKS_RETALIATION.name": "Bez kontrataku",
|
||||
"core.bonus.BLOCKS_RETALIATION.description": "Wróg nie może kontratakować",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.name": "Brak kontrataku dystansowego",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.description": "Wróg nie może kontratakować poprzez strzelanie",
|
||||
"core.bonus.CATAPULT.name": "Katapulta",
|
||||
"core.bonus.CATAPULT.description": "Atakuje mury obronne",
|
||||
"core.bonus.CATAPULT_EXTRA_SHOTS.name": "Dodatkowe ataki oblężnicze",
|
||||
"core.bonus.CATAPULT_EXTRA_SHOTS.description": "Może uderzyć mury obronne ${val} dodatkowych razy na atak",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ALLY.name": "Zmniejsz koszt czarów (${val})",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ALLY.description": "Zmniejsza koszt czaru bohatera",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.name": "Tłumienie magii (${val})",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.description": "Zwiększa koszt wrogich czarów",
|
||||
"core.bonus.CHARGE_IMMUNITY.name": "Odporność na szarżę",
|
||||
"core.bonus.CHARGE_IMMUNITY.description": "Odporny na szarżę czempionów",
|
||||
"core.bonus.DARKNESS.name": "Całun ciemności",
|
||||
"core.bonus.DARKNESS.description": "Generuje ${val} wartości promienia mgły wojny",
|
||||
"core.bonus.DEATH_STARE.name": "Spojrzenie Śmierci (${val}%)",
|
||||
"core.bonus.DEATH_STARE.description": "${val}% szans na zabicie jednego stworzenia",
|
||||
"core.bonus.DEFENSIVE_STANCE.name": "Bonus do obrony",
|
||||
"core.bonus.DEFENSIVE_STANCE.description": "+${val} Obrony kiedy broni",
|
||||
"core.bonus.DESTRUCTION.name": "Destrukcja",
|
||||
"core.bonus.DESTRUCTION.description": "Ma ${val}% szans na zabicie dodatkowych jednostek po ataku",
|
||||
"core.bonus.DOUBLE_DAMAGE_CHANCE.name": "Uderzenie Śmierci",
|
||||
"core.bonus.DOUBLE_DAMAGE_CHANCE.description": "${val}% szans na podwójne obrażenia",
|
||||
"core.bonus.DRAGON_NATURE.name": "Smok",
|
||||
"core.bonus.DRAGON_NATURE.description": "Stworzenie posiada smoczą naturę",
|
||||
"core.bonus.DIRECT_DAMAGE_IMMUNITY.name": "Odporność na bezpośrednie obrażenia",
|
||||
"core.bonus.DIRECT_DAMAGE_IMMUNITY.description": "Odporny na czary zadające bezpośrednie obrażenia",
|
||||
"core.bonus.EARTH_IMMUNITY.name": "Odporność na ziemię",
|
||||
"core.bonus.EARTH_IMMUNITY.description": "Odporny na wszystkie czary szkoły ziemi",
|
||||
"core.bonus.ENCHANTER.name": "Czarodziej",
|
||||
"core.bonus.ENCHANTER.description": "Może rzucać masowy czar ${subtype.spell} każdej tury",
|
||||
"core.bonus.ENCHANTED.name": "Zaczarowany",
|
||||
"core.bonus.ENCHANTED.description": "Pod wpływem trwałego ${subtype.spell}",
|
||||
"core.bonus.ENEMY_DEFENCE_REDUCTION.name": "Ignoruje Obronę (${val}%)",
|
||||
"core.bonus.ENEMY_DEFENCE_REDUCTION.description": "Ignoruje część obrony podczas ataku",
|
||||
"core.bonus.FIRE_IMMUNITY.name": "Odporność na ogień",
|
||||
"core.bonus.FIRE_IMMUNITY.description": "Odporny na wszystkie czary szkoły ognia",
|
||||
"core.bonus.FIRE_SHIELD.name": "Ognista tarcza (${val}%)",
|
||||
"core.bonus.FIRE_SHIELD.description": "Odbija część obrażeń z walki wręcz",
|
||||
"core.bonus.FIRST_STRIKE.name": "Pierwsze Uderzenie",
|
||||
"core.bonus.FIRST_STRIKE.description": "To stworzenie atakuje pierwsze w ramach kontrataku",
|
||||
"core.bonus.FEAR.name": "Strach",
|
||||
"core.bonus.FEAR.description": "Wzbudza strach na wrogim stworzeniu",
|
||||
"core.bonus.FEARLESS.name": "Nieustraszony",
|
||||
"core.bonus.FEARLESS.description": "Odporny na strach",
|
||||
"core.bonus.FLYING.name": "Lot",
|
||||
"core.bonus.FLYING.description": "Może latać (ignoruje przeszkody)",
|
||||
"core.bonus.FREE_SHOOTING.name": "Bliski Strzał",
|
||||
"core.bonus.FREE_SHOOTING.description": "Może strzelać w zasięgu walki wręcz",
|
||||
"core.bonus.FULL_HP_REGENERATION.name": "Regeneracja",
|
||||
"core.bonus.FULL_HP_REGENERATION.description": "Może zregenerować się do pełni zdrowia",
|
||||
"core.bonus.GARGOYLE.name": "Gargulec",
|
||||
"core.bonus.GARGOYLE.description": "Nie może być wskrzeszony lub uleczony",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.name": "Zmniejsz obrażenia (${val}%)",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.description": "Zmiejsza obrażenia fizyczne z dystansu lub walki wręcz",
|
||||
"core.bonus.HATE.name": "Nienawidzi ${subtype.creature}",
|
||||
"core.bonus.HATE.description": "Zadaje ${val}% więcej obrażeń",
|
||||
"core.bonus.HEALER.name": "Uzdrowiciel",
|
||||
"core.bonus.HEALER.description": "Leczy sprzymierzone jednostki",
|
||||
"core.bonus.HP_REGENERATION.name": "Regeneracja",
|
||||
"core.bonus.HP_REGENERATION.description": "Leczy ${val} punktów zdrowia każdej rundy",
|
||||
"core.bonus.JOUSTING.name": "Szarża Czempiona",
|
||||
"core.bonus.JOUSTING.description": "+5% obrażeń na przebytego heksa",
|
||||
"core.bonus.KING1.name": "Król 1",
|
||||
"core.bonus.KING1.description": "Wrażliwy na podstawowy czar POGROMCA",
|
||||
"core.bonus.KING2.name": "Król 2",
|
||||
"core.bonus.KING2.description": "Wrażliwy na zaawansowany czar POGROMCA",
|
||||
"core.bonus.KING3.name": "Król 3",
|
||||
"core.bonus.KING3.description":"Wrażliwy na ekspercki czar POGROMCA",
|
||||
"core.bonus.LEVEL_SPELL_IMMUNITY.name": "Odporność na czary 1-${val}",
|
||||
"core.bonus.LEVEL_SPELL_IMMUNITY.description": "Odporny na czary 1-${val} poziomu",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.name" : "Ograniczony zasięg strzelania",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.description" : "Nie może strzelać do celów będących dalej niż ${val} heksów",
|
||||
"core.bonus.LIFE_DRAIN.name": "Wysysa życie (${val}%)",
|
||||
"core.bonus.LIFE_DRAIN.description": "Wysysa ${val}% zadanych obrażeń",
|
||||
"core.bonus.MANA_CHANNELING.name": "Transfer many ${val}%",
|
||||
"core.bonus.MANA_CHANNELING.description": "Daje twojemu bohaterowi manę zużytą przez przeciwnika",
|
||||
"core.bonus.MANA_DRAIN.name": "Wyssanie many",
|
||||
"core.bonus.MANA_DRAIN.description": "Wysysa ${val} many każdej tury",
|
||||
"core.bonus.MAGIC_MIRROR.name": "Magiczne Zwierciadło (${val}%)",
|
||||
"core.bonus.MAGIC_MIRROR.description": "${val}% szans na odbicie ofensywnego czaru do wroga",
|
||||
"core.bonus.MAGIC_RESISTANCE.name": "Odporność na Magię(${MR}%)",
|
||||
"core.bonus.MAGIC_RESISTANCE.description": "${MR}% szans na przeciwstawienie się wrogiemu czarowi",
|
||||
"core.bonus.MIND_IMMUNITY.name": "Odporność na czasy umysłu",
|
||||
"core.bonus.MIND_IMMUNITY.description": "Odporny na czary typu umysłu",
|
||||
"core.bonus.NO_DISTANCE_PENALTY.name": "Brak ograniczeń za odległość",
|
||||
"core.bonus.NO_DISTANCE_PENALTY.description": "Pełne obrażenia z każdego zasięgu",
|
||||
"core.bonus.NO_MELEE_PENALTY.name": "Brak ograniczeń za walkę wręcz",
|
||||
"core.bonus.NO_MELEE_PENALTY.description": "Stworzenie nie ma kar w walce wręcz",
|
||||
"core.bonus.NO_MORALE.name": "Neutralne Morale",
|
||||
"core.bonus.NO_MORALE.description": "Stworzenie jest odporne na efekty morale",
|
||||
"core.bonus.NO_WALL_PENALTY.name": "Brak kar za strzelanie przez przeszkody",
|
||||
"core.bonus.NO_WALL_PENALTY.description": "Pełne obrażenia podczas oblężenia",
|
||||
"core.bonus.NON_LIVING.name": "Nie żyjący",
|
||||
"core.bonus.NON_LIVING.description": "Niewrażliwość na wiele efektów",
|
||||
"core.bonus.RANDOM_SPELLCASTER.name": "Losowy czarodziej",
|
||||
"core.bonus.RANDOM_SPELLCASTER.description": "Może rzucić losowy czar",
|
||||
"core.bonus.RANGED_RETALIATION.name": "Dystansowy kontratak",
|
||||
"core.bonus.RANGED_RETALIATION.description": "Może wykonać kontratak dystansowy",
|
||||
"core.bonus.RECEPTIVE.name": "Absorpcyjny",
|
||||
"core.bonus.RECEPTIVE.description": "Brak odporności na przyjazne zaklęcia",
|
||||
"core.bonus.REBIRTH.name": "Odrodzenie (${val}%)",
|
||||
"core.bonus.REBIRTH.description": "${val}% stworzeń powstanie po śmierci",
|
||||
"core.bonus.RETURN_AFTER_STRIKE.name": "Atak i Powrót",
|
||||
"core.bonus.RETURN_AFTER_STRIKE.description": "Wraca po ataku wręcz",
|
||||
"core.bonus.SELF_LUCK.name": "Pozytywne szczęście",
|
||||
"core.bonus.SELF_LUCK.description": "Zawsze posiada pozytywne szczęście",
|
||||
"core.bonus.SELF_MORALE.name": "Pozytywne Morale",
|
||||
"core.bonus.SELF_MORALE.description": "Zawsze posiada pozytywne morale",
|
||||
"core.bonus.SHOOTER.name": "Dystansowy",
|
||||
"core.bonus.SHOOTER.description": "Stworzenie może strzelać",
|
||||
"core.bonus.SHOOTS_ALL_ADJACENT.name": "Ostrzeliwuje wszystko dookoła",
|
||||
"core.bonus.SHOOTS_ALL_ADJACENT.description": "Ataki dystansowe tego stworzenia uderzają we wszystkie cele na małym obszarze",
|
||||
"core.bonus.SOUL_STEAL.name": "Kradzież dusz",
|
||||
"core.bonus.SOUL_STEAL.description": "Zdobywa ${val} nowych stworzeń za każdego zabitego wroga",
|
||||
"core.bonus.SPELLCASTER.name": "Czarodziej",
|
||||
"core.bonus.SPELLCASTER.description": "Może rzucić ${subtype.spell}",
|
||||
"core.bonus.SPELL_AFTER_ATTACK.name": "Rzuca czar po ataku",
|
||||
"core.bonus.SPELL_AFTER_ATTACK.description": "${val}% szans aby rzucić ${subtype.spell} po ataku",
|
||||
"core.bonus.SPELL_BEFORE_ATTACK.name": "Rzuca czar przed atakiem",
|
||||
"core.bonus.SPELL_BEFORE_ATTACK.description": "${val}% szans aby rzucić ${subtype.spell} przed atakiem",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.name": "Odporność na czary",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description": "Obrażenia od czarów są zmniejszone o ${val}%.",
|
||||
"core.bonus.SPELL_IMMUNITY.name": "Odporność na czar",
|
||||
"core.bonus.SPELL_IMMUNITY.description": "Odporny na ${subtype.spell}",
|
||||
"core.bonus.SPELL_LIKE_ATTACK.name": "Atak czaropodobny",
|
||||
"core.bonus.SPELL_LIKE_ATTACK.description": "Atakuje z użyciem ${subtype.spell}",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.name": "Aura Odporności",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.description": "Pobliskie stworzenia otrzymują ${val}% magicznej odporności",
|
||||
"core.bonus.SUMMON_GUARDIANS.name": "Wezwij strażników",
|
||||
"core.bonus.SUMMON_GUARDIANS.description": "Na początku walki wzywa ${subtype.creature} (${val}%)",
|
||||
"core.bonus.SYNERGY_TARGET.name": "Synergiczny",
|
||||
"core.bonus.SYNERGY_TARGET.description": "To stworzenie jest podatne na efekt synergii",
|
||||
"core.bonus.TWO_HEX_ATTACK_BREATH.name": "Zionięcie",
|
||||
"core.bonus.TWO_HEX_ATTACK_BREATH.description": "Atak zionący (zasięg 2 heksów)",
|
||||
"core.bonus.THREE_HEADED_ATTACK.name": "Atak trzema głowami",
|
||||
"core.bonus.THREE_HEADED_ATTACK.description": "Atakuje trzy sąsiadujące jednostki",
|
||||
"core.bonus.TRANSMUTATION.name": "Transmutacja",
|
||||
"core.bonus.TRANSMUTATION.description": "${val}% szans aby przetransformować atakowaną jednostkę na inny typ",
|
||||
"core.bonus.UNDEAD.name": "Nieumarły",
|
||||
"core.bonus.UNDEAD.description": "Stworzenie jest nieumarłe",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.name": "Nieskończone kontrataki",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.description": "Kontratakuje nieskończoną ilość razy",
|
||||
"core.bonus.WATER_IMMUNITY.name": "Odporność na wodę",
|
||||
"core.bonus.WATER_IMMUNITY.description": "Odporny na wszystkie czary szkoły wody",
|
||||
"core.bonus.WIDE_BREATH.name": "Szerokie zionięcie",
|
||||
"core.bonus.WIDE_BREATH.description": "Szeroki atak zionięciem (wiele heksów)"
|
||||
}
|
||||
|
@ -14,10 +14,10 @@
|
||||
},
|
||||
|
||||
"polish" : {
|
||||
"name" : "VCMI essential files",
|
||||
"description" : "Essential files required for VCMI to run correctly",
|
||||
"author" : "VCMI Team",
|
||||
"modType" : "Graphical",
|
||||
"name" : "Podstawowe pliki VCMI",
|
||||
"description" : "Dodatkowe pliki wymagane do prawidłowego działania VCMI",
|
||||
"author" : "Zespół VCMI",
|
||||
"modType" : "Graficzny",
|
||||
|
||||
"translations" : [
|
||||
"config/vcmi/polish.json"
|
||||
|
@ -1,6 +1,7 @@
|
||||
[![GitHub](https://github.com/vcmi/vcmi/actions/workflows/github.yml/badge.svg)](https://github.com/vcmi/vcmi/actions/workflows/github.yml)
|
||||
[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/github/vcmi/vcmi?branch=develop&svg=true)](https://ci.appveyor.com/project/vcmi/vcmi)
|
||||
[![Coverity Scan Build Status](https://scan.coverity.com/projects/vcmi/badge.svg)](https://scan.coverity.com/projects/vcmi)
|
||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.1.1/total)](https://github.com/vcmi/vcmi/releases/tag/1.1.1)
|
||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.1.0/total)](https://github.com/vcmi/vcmi/releases/tag/1.1.0)
|
||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases)
|
||||
# VCMI Project
|
||||
|
@ -54,7 +54,7 @@
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef VCMI_WINDOWS
|
||||
#include "SDL_syswm.h"
|
||||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
#ifdef VCMI_ANDROID
|
||||
#include "lib/CAndroidVMHelper.h"
|
||||
@ -839,7 +839,7 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
|
||||
}
|
||||
|
||||
|
||||
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
#ifdef VCMI_ENDIAN_BIG
|
||||
int bmask = 0xff000000;
|
||||
int gmask = 0x00ff0000;
|
||||
int rmask = 0x0000ff00;
|
||||
@ -949,7 +949,7 @@ static void handleEvent(SDL_Event & ev)
|
||||
}
|
||||
else if(ev.type == SDL_USEREVENT)
|
||||
{
|
||||
switch(ev.user.code)
|
||||
switch(static_cast<EUserEvent>(ev.user.code))
|
||||
{
|
||||
case EUserEvent::FORCE_QUIT:
|
||||
{
|
||||
@ -1050,7 +1050,7 @@ static void handleEvent(SDL_Event & ev)
|
||||
static void mainLoop()
|
||||
{
|
||||
SettingsListener resChanged = settings.listen["video"]["fullscreen"];
|
||||
resChanged([](const JsonNode &newState){ CGuiHandler::pushSDLEvent(SDL_USEREVENT, EUserEvent::FULLSCREEN_TOGGLED); });
|
||||
resChanged([](const JsonNode &newState){ CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
|
||||
|
||||
inGuiThread.reset(new bool(true));
|
||||
GH.mainFPSmng->init();
|
||||
|
@ -54,6 +54,7 @@ set(client_SRCS
|
||||
render/CFadeAnimation.cpp
|
||||
render/Canvas.cpp
|
||||
render/ColorFilter.cpp
|
||||
render/Colors.cpp
|
||||
render/Graphics.cpp
|
||||
render/IFont.cpp
|
||||
|
||||
@ -140,6 +141,7 @@ set(client_HEADERS
|
||||
gui/CIntObject.h
|
||||
gui/CursorHandler.h
|
||||
gui/InterfaceObjectConfigurable.h
|
||||
gui/MouseButton.h
|
||||
gui/NotificationHandler.h
|
||||
gui/TextAlignment.h
|
||||
|
||||
@ -164,6 +166,7 @@ set(client_HEADERS
|
||||
render/CFadeAnimation.h
|
||||
render/Canvas.h
|
||||
render/ColorFilter.h
|
||||
render/Colors.h
|
||||
render/Graphics.h
|
||||
render/ICursor.h
|
||||
render/IFont.h
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "gui/CursorHandler.h"
|
||||
#include "windows/CKingdomInterface.h"
|
||||
#include "CGameInfo.h"
|
||||
#include "CMT.h"
|
||||
#include "windows/CHeroWindow.h"
|
||||
#include "windows/CCreatureWindow.h"
|
||||
#include "windows/CQuestLog.h"
|
||||
@ -87,8 +88,6 @@
|
||||
return; \
|
||||
RETURN_IF_QUICK_COMBAT
|
||||
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
extern std::queue<SDL_Event> SDLEventsQueue;
|
||||
extern boost::mutex eventsM;
|
||||
boost::recursive_mutex * CPlayerInterface::pim = new boost::recursive_mutex;
|
||||
@ -1043,7 +1042,7 @@ void CPlayerInterface::showComp(const Component &comp, std::string message)
|
||||
void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<Component> & components, int soundID)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if (settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed())
|
||||
if (settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1067,7 +1066,7 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
|
||||
LOG_TRACE_PARAMS(logGlobal, "player=%s, text=%s, is LOCPLINT=%d", playerID % text % (this==LOCPLINT));
|
||||
waitWhileDialog();
|
||||
|
||||
if (settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed())
|
||||
if (settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1328,16 +1327,6 @@ void CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
||||
boost::thread moveHeroTask(std::bind(&CPlayerInterface::doMoveHero,this,h,path));
|
||||
}
|
||||
|
||||
bool CPlayerInterface::shiftPressed() const
|
||||
{
|
||||
return isShiftKeyDown();
|
||||
}
|
||||
|
||||
bool CPlayerInterface::altPressed() const
|
||||
{
|
||||
return isAltKeyDown();
|
||||
}
|
||||
|
||||
void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
@ -1558,11 +1547,6 @@ void CPlayerInterface::playerBlocked(int reason, bool start)
|
||||
}
|
||||
}
|
||||
|
||||
bool CPlayerInterface::ctrlPressed() const
|
||||
{
|
||||
return isCtrlKeyDown();
|
||||
}
|
||||
|
||||
const CArmedInstance * CPlayerInterface::getSelection()
|
||||
{
|
||||
return currentSelection;
|
||||
@ -1604,7 +1588,7 @@ void CPlayerInterface::update()
|
||||
|
||||
if (!adventureInt || adventureInt->isActive())
|
||||
GH.simpleRedraw();
|
||||
else if((adventureInt->swipeEnabled && adventureInt->swipeMovementRequested) || adventureInt->scrollingDir)
|
||||
else if((adventureInt->swipeEnabled && adventureInt->swipeMovementRequested) || (adventureInt->scrollingDir && GH.isKeyboardCtrlDown()))
|
||||
GH.totalRedraw(); //player forces map scrolling though interface is disabled
|
||||
else
|
||||
GH.simpleRedraw();
|
||||
@ -1990,7 +1974,7 @@ void CPlayerInterface::acceptTurn()
|
||||
adventureInt->updateNextHero(nullptr);
|
||||
adventureInt->showAll(screen);
|
||||
|
||||
if(settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed())
|
||||
if(settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown())
|
||||
{
|
||||
if(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt().get()))
|
||||
iw->close();
|
||||
@ -2154,12 +2138,7 @@ void CPlayerInterface::requestReturningToMainMenu(bool won)
|
||||
if(won && cb->getStartInfo()->campState)
|
||||
CSH->startCampaignScenario(cb->getStartInfo()->campState);
|
||||
else
|
||||
sendCustomEvent(EUserEvent::RETURN_TO_MAIN_MENU);
|
||||
}
|
||||
|
||||
void CPlayerInterface::sendCustomEvent( int code )
|
||||
{
|
||||
CGuiHandler::pushSDLEvent(SDL_USEREVENT, code);
|
||||
GH.pushUserEvent(EUserEvent::RETURN_TO_MAIN_MENU);
|
||||
}
|
||||
|
||||
void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al)
|
||||
@ -2283,7 +2262,7 @@ void CPlayerInterface::waitForAllDialogs(bool unlockPim)
|
||||
|
||||
void CPlayerInterface::proposeLoadingGame()
|
||||
{
|
||||
showYesNoDialog(CGI->generaltexth->allTexts[68], [this](){ sendCustomEvent(EUserEvent::RETURN_TO_MENU_LOAD); }, nullptr);
|
||||
showYesNoDialog(CGI->generaltexth->allTexts[68], [](){ GH.pushUserEvent(EUserEvent::RETURN_TO_MENU_LOAD); }, nullptr);
|
||||
}
|
||||
|
||||
CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
|
||||
|
@ -213,9 +213,6 @@ public:
|
||||
void heroKilled(const CGHeroInstance* hero);
|
||||
void waitWhileDialog(bool unlockPim = true);
|
||||
void waitForAllDialogs(bool unlockPim = true);
|
||||
bool shiftPressed() const; //determines if shift key is pressed (left or right or both)
|
||||
bool ctrlPressed() const; //determines if ctrl key is pressed (left or right or both)
|
||||
bool altPressed() const; //determines if alt key is pressed (left or right or both)
|
||||
void redrawHeroWin(const CGHeroInstance * hero);
|
||||
void openTownWindow(const CGTownInstance * town); //shows townscreen
|
||||
void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
|
||||
@ -243,7 +240,6 @@ public:
|
||||
void tryDiggging(const CGHeroInstance *h);
|
||||
void showShipyardDialogOrProblemPopup(const IShipyard *obj); //obj may be town or shipyard;
|
||||
void requestReturningToMainMenu(bool won);
|
||||
void sendCustomEvent(int code);
|
||||
void proposeLoadingGame();
|
||||
|
||||
// Ambient sounds
|
||||
|
@ -60,8 +60,6 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
template<typename T> class CApplyOnLobby;
|
||||
|
||||
const std::string CServerHandler::localhostAddress{"127.0.0.1"};
|
||||
@ -655,14 +653,10 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
||||
|
||||
void CServerHandler::startCampaignScenario(std::shared_ptr<CCampaignState> cs)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = EUserEvent::CAMPAIGN_START_SCENARIO;
|
||||
if(cs)
|
||||
event.user.data1 = CMemorySerializer::deepCopy(*cs.get()).release();
|
||||
GH.pushUserEvent(EUserEvent::CAMPAIGN_START_SCENARIO, CMemorySerializer::deepCopy(*cs.get()).release());
|
||||
else
|
||||
event.user.data1 = CMemorySerializer::deepCopy(*si->campState.get()).release();
|
||||
SDL_PushEvent(&event);
|
||||
GH.pushUserEvent(EUserEvent::CAMPAIGN_START_SCENARIO, CMemorySerializer::deepCopy(*si->campState.get()).release());
|
||||
}
|
||||
|
||||
void CServerHandler::showServerError(std::string txt)
|
||||
@ -824,7 +818,7 @@ void CServerHandler::threadHandleConnection()
|
||||
if(client)
|
||||
{
|
||||
state = EClientState::DISCONNECTING;
|
||||
CGuiHandler::pushSDLEvent(SDL_USEREVENT, EUserEvent::RETURN_TO_MAIN_MENU);
|
||||
CGuiHandler::pushUserEvent(EUserEvent::RETURN_TO_MAIN_MENU);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "CVideoHandler.h"
|
||||
|
||||
#include "CMT.h"
|
||||
#include "gui/CGuiHandler.h"
|
||||
#include "renderSDL/SDL_Extensions.h"
|
||||
#include "CPlayerInterface.h"
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../windows/SettingsMainContainer.h"
|
||||
#include "../CMT.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
@ -43,9 +44,6 @@
|
||||
#include "../../lib/UnlockGuard.h"
|
||||
#include "../../lib/TerrainHandler.h"
|
||||
|
||||
#include <SDL_surface.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
#define ADVOPT (conf.go()->ac)
|
||||
|
||||
std::shared_ptr<CAdvMapInt> adventureInt;
|
||||
@ -91,8 +89,8 @@ CAdvMapInt::CAdvMapInt():
|
||||
swipeTargetPosition(int3(-1, -1, -1))
|
||||
{
|
||||
pos.x = pos.y = 0;
|
||||
pos.w = screen->w;
|
||||
pos.h = screen->h;
|
||||
pos.w = GH.screenDimensions().x;
|
||||
pos.h = GH.screenDimensions().y;
|
||||
strongInterest = true; // handle all mouse move events to prevent dead mouse move space in fullscreen mode
|
||||
townList.onSelect = std::bind(&CAdvMapInt::selectionChanged,this);
|
||||
bg = IImage::createFromFile(ADVOPT.mainGraphic);
|
||||
@ -138,7 +136,7 @@ CAdvMapInt::CAdvMapInt():
|
||||
nextHero = makeButton(301, std::bind(&CAdvMapInt::fnextHero,this), ADVOPT.nextHero, SDLK_h);
|
||||
endTurn = makeButton(302, std::bind(&CAdvMapInt::fendTurn,this), ADVOPT.endTurn, SDLK_e);
|
||||
|
||||
int panelSpaceBottom = screen->h - resdatabar.pos.h - 4;
|
||||
int panelSpaceBottom = GH.screenDimensions().y - resdatabar.pos.h - 4;
|
||||
|
||||
panelMain = std::make_shared<CAdvMapPanel>(nullptr, Point(0, 0));
|
||||
// TODO correct drawing position
|
||||
@ -159,7 +157,7 @@ CAdvMapInt::CAdvMapInt():
|
||||
// TODO move configs to resolutions.json, similarly to previous buttons
|
||||
config::ButtonInfo worldViewBackConfig = config::ButtonInfo();
|
||||
worldViewBackConfig.defName = "IOK6432.DEF";
|
||||
worldViewBackConfig.x = screen->w - 73;
|
||||
worldViewBackConfig.x = GH.screenDimensions().x - 73;
|
||||
worldViewBackConfig.y = 343 + 195;
|
||||
worldViewBackConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel(
|
||||
@ -167,7 +165,7 @@ CAdvMapInt::CAdvMapInt():
|
||||
|
||||
config::ButtonInfo worldViewPuzzleConfig = config::ButtonInfo();
|
||||
worldViewPuzzleConfig.defName = "VWPUZ.DEF";
|
||||
worldViewPuzzleConfig.x = screen->w - 188;
|
||||
worldViewPuzzleConfig.x = GH.screenDimensions().x - 188;
|
||||
worldViewPuzzleConfig.y = 343 + 195;
|
||||
worldViewPuzzleConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // no help text for this one
|
||||
@ -176,7 +174,7 @@ CAdvMapInt::CAdvMapInt():
|
||||
|
||||
config::ButtonInfo worldViewScale1xConfig = config::ButtonInfo();
|
||||
worldViewScale1xConfig.defName = "VWMAG1.DEF";
|
||||
worldViewScale1xConfig.x = screen->w - 191;
|
||||
worldViewScale1xConfig.x = GH.screenDimensions().x - 191;
|
||||
worldViewScale1xConfig.y = 23 + 195;
|
||||
worldViewScale1xConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // help text is wrong for this button
|
||||
@ -184,7 +182,7 @@ CAdvMapInt::CAdvMapInt():
|
||||
|
||||
config::ButtonInfo worldViewScale2xConfig = config::ButtonInfo();
|
||||
worldViewScale2xConfig.defName = "VWMAG2.DEF";
|
||||
worldViewScale2xConfig.x = screen->w - 191 + 63;
|
||||
worldViewScale2xConfig.x = GH.screenDimensions().x- 191 + 63;
|
||||
worldViewScale2xConfig.y = 23 + 195;
|
||||
worldViewScale2xConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // help text is wrong for this button
|
||||
@ -192,7 +190,7 @@ CAdvMapInt::CAdvMapInt():
|
||||
|
||||
config::ButtonInfo worldViewScale4xConfig = config::ButtonInfo();
|
||||
worldViewScale4xConfig.defName = "VWMAG4.DEF";
|
||||
worldViewScale4xConfig.x = screen->w - 191 + 126;
|
||||
worldViewScale4xConfig.x = GH.screenDimensions().x- 191 + 126;
|
||||
worldViewScale4xConfig.y = 23 + 195;
|
||||
worldViewScale4xConfig.playerColoured = false;
|
||||
panelWorldView->addChildToPanel( // help text is wrong for this button
|
||||
@ -201,7 +199,7 @@ CAdvMapInt::CAdvMapInt():
|
||||
config::ButtonInfo worldViewUndergroundConfig = config::ButtonInfo();
|
||||
worldViewUndergroundConfig.defName = "IAM010.DEF";
|
||||
worldViewUndergroundConfig.additionalDefs.push_back("IAM003.DEF");
|
||||
worldViewUndergroundConfig.x = screen->w - 115;
|
||||
worldViewUndergroundConfig.x = GH.screenDimensions().x - 115;
|
||||
worldViewUndergroundConfig.y = 343 + 195;
|
||||
worldViewUndergroundConfig.playerColoured = true;
|
||||
worldViewUnderground = makeButton(294, std::bind(&CAdvMapInt::fswitchLevel,this), worldViewUndergroundConfig, SDLK_u);
|
||||
@ -617,7 +615,7 @@ void CAdvMapInt::handleMapScrollingUpdate()
|
||||
int scrollSpeed = static_cast<int>(settings["adventure"]["scrollSpeed"].Float());
|
||||
//if advmap needs updating AND (no dialog is shown OR ctrl is pressed)
|
||||
if((animValHitCount % (4 / scrollSpeed)) == 0
|
||||
&& ((GH.topInt().get() == this) || CSDL_Ext::isCtrlKeyDown()))
|
||||
&& GH.isKeyboardCtrlDown())
|
||||
{
|
||||
if((scrollingDir & LEFT) && (position.x > -CGI->mh->frameW))
|
||||
position.x--;
|
||||
@ -713,21 +711,46 @@ void CAdvMapInt::centerOn(const CGObjectInstance * obj, bool fade)
|
||||
centerOn(obj->getSightCenter(), fade);
|
||||
}
|
||||
|
||||
void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void CAdvMapInt::keyReleased(const SDL_Keycode &key)
|
||||
{
|
||||
if (mode == EAdvMapMode::WORLD_VIEW)
|
||||
return;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case SDLK_s:
|
||||
if(isActive())
|
||||
GH.pushIntT<CSavingScreen>();
|
||||
return;
|
||||
default:
|
||||
{
|
||||
auto direction = keyToMoveDirection(key);
|
||||
|
||||
if (!direction)
|
||||
return;
|
||||
|
||||
ui8 Dir = (direction->x<0 ? LEFT : 0) |
|
||||
(direction->x>0 ? RIGHT : 0) |
|
||||
(direction->y<0 ? UP : 0) |
|
||||
(direction->y>0 ? DOWN : 0) ;
|
||||
|
||||
scrollingDir &= ~Dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAdvMapInt::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
|
||||
if (mode == EAdvMapMode::WORLD_VIEW)
|
||||
return;
|
||||
|
||||
ui8 Dir = 0;
|
||||
SDL_Keycode k = key.keysym.sym;
|
||||
const CGHeroInstance *h = curHero(); //selected hero
|
||||
const CGTownInstance *t = curTown(); //selected town
|
||||
|
||||
switch(k)
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_g:
|
||||
if(key.state != SDL_PRESSED || GH.topInt()->type & BLOCK_ADV_HOTKEYS)
|
||||
if(GH.topInt()->type & BLOCK_ADV_HOTKEYS)
|
||||
return;
|
||||
|
||||
{
|
||||
@ -751,13 +774,9 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
if(isActive())
|
||||
LOCPLINT->proposeLoadingGame();
|
||||
return;
|
||||
case SDLK_s:
|
||||
if(isActive() && key.type == SDL_KEYUP)
|
||||
GH.pushIntT<CSavingScreen>();
|
||||
return;
|
||||
case SDLK_d:
|
||||
{
|
||||
if(h && isActive() && LOCPLINT->makingTurn && key.state == SDL_PRESSED)
|
||||
if(h && isActive() && LOCPLINT->makingTurn)
|
||||
LOCPLINT->tryDiggging(h);
|
||||
return;
|
||||
}
|
||||
@ -770,17 +789,17 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
LOCPLINT->viewWorldMap();
|
||||
return;
|
||||
case SDLK_r:
|
||||
if(isActive() && LOCPLINT->ctrlPressed())
|
||||
if(isActive() && GH.isKeyboardCtrlDown())
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
|
||||
[](){ LOCPLINT->sendCustomEvent(EUserEvent::RESTART_GAME); }, nullptr);
|
||||
[](){ GH.pushUserEvent(EUserEvent::RESTART_GAME); }, nullptr);
|
||||
}
|
||||
return;
|
||||
case SDLK_SPACE: //space - try to revisit current object with selected hero
|
||||
{
|
||||
if(!isActive())
|
||||
return;
|
||||
if(h && key.state == SDL_PRESSED)
|
||||
if(h)
|
||||
{
|
||||
auto unlockPim = vstd::makeUnlockGuard(*CPlayerInterface::pim);
|
||||
//TODO!!!!!!! possible freeze, when GS mutex is locked and network thread can't apply package
|
||||
@ -793,7 +812,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
return;
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
if(!isActive() || !selection || key.state != SDL_PRESSED)
|
||||
if(!isActive() || !selection)
|
||||
return;
|
||||
if(h)
|
||||
LOCPLINT->openHeroWindow(h);
|
||||
@ -803,7 +822,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
case SDLK_ESCAPE:
|
||||
{
|
||||
if(isActive() || GH.topInt().get() != this || !spellBeingCasted || key.state != SDL_PRESSED)
|
||||
if(isActive() || GH.topInt().get() != this || !spellBeingCasted)
|
||||
return;
|
||||
|
||||
leaveCastingMode();
|
||||
@ -812,10 +831,10 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
case SDLK_t:
|
||||
{
|
||||
//act on key down if marketplace windows is not already opened
|
||||
if(key.state != SDL_PRESSED || GH.topInt()->type & BLOCK_ADV_HOTKEYS)
|
||||
if(GH.topInt()->type & BLOCK_ADV_HOTKEYS)
|
||||
return;
|
||||
|
||||
if(LOCPLINT->ctrlPressed()) //CTRL + T => open marketplace
|
||||
if(GH.isKeyboardCtrlDown()) //CTRL + T => open marketplace
|
||||
{
|
||||
//check if we have any marketplace
|
||||
const CGTownInstance *townWithMarket = nullptr;
|
||||
@ -841,37 +860,29 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
default:
|
||||
{
|
||||
static const int3 directions[] = { int3(-1, +1, 0), int3(0, +1, 0), int3(+1, +1, 0),
|
||||
int3(-1, 0, 0), int3(0, 0, 0), int3(+1, 0, 0),
|
||||
int3(-1, -1, 0), int3(0, -1, 0), int3(+1, -1, 0) };
|
||||
auto direction = keyToMoveDirection(key);
|
||||
|
||||
//numpad arrow
|
||||
if(CGuiHandler::isArrowKey(k))
|
||||
k = CGuiHandler::arrowToNum(k);
|
||||
if (!direction)
|
||||
return;
|
||||
|
||||
k -= SDLK_KP_1;
|
||||
ui8 Dir = (direction->x<0 ? LEFT : 0) |
|
||||
(direction->x>0 ? RIGHT : 0) |
|
||||
(direction->y<0 ? UP : 0) |
|
||||
(direction->y>0 ? DOWN : 0) ;
|
||||
|
||||
if(k < 0 || k > 8)
|
||||
scrollingDir |= Dir;
|
||||
|
||||
//ctrl makes arrow move screen, not hero
|
||||
if(GH.isKeyboardCtrlDown())
|
||||
return;
|
||||
|
||||
if(!h || !isActive())
|
||||
return;
|
||||
|
||||
if (!CGI->mh->canStartHeroMovement())
|
||||
return;
|
||||
|
||||
int3 dir = directions[k];
|
||||
|
||||
if(!isActive() || LOCPLINT->ctrlPressed())//ctrl makes arrow move screen, not hero
|
||||
{
|
||||
Dir = (dir.x<0 ? LEFT : 0) |
|
||||
(dir.x>0 ? RIGHT : 0) |
|
||||
(dir.y<0 ? UP : 0) |
|
||||
(dir.y>0 ? DOWN : 0) ;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!h || key.state != SDL_PRESSED)
|
||||
break;
|
||||
|
||||
if(k == 4)
|
||||
if(*direction == Point(0,0))
|
||||
{
|
||||
centerOn(h);
|
||||
return;
|
||||
@ -879,7 +890,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
|
||||
CGPath &path = LOCPLINT->paths[h];
|
||||
terrain.currentPath = &path;
|
||||
int3 dst = h->visitablePos() + dir;
|
||||
int3 dst = h->visitablePos() + int3(direction->x, direction->y, 0);
|
||||
if(dst != verifyPos(dst) || !LOCPLINT->cb->getPathsInfo(h)->getPath(path, dst))
|
||||
{
|
||||
terrain.currentPath = nullptr;
|
||||
@ -895,13 +906,29 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
|
||||
return;
|
||||
}
|
||||
if(Dir && key.state == SDL_PRESSED //arrow is pressed
|
||||
&& LOCPLINT->ctrlPressed()
|
||||
)
|
||||
scrollingDir |= Dir;
|
||||
else
|
||||
scrollingDir &= ~Dir;
|
||||
}
|
||||
|
||||
boost::optional<Point> CAdvMapInt::keyToMoveDirection(const SDL_Keycode & key)
|
||||
{
|
||||
switch (key) {
|
||||
case SDLK_DOWN: return Point( 0, +1);
|
||||
case SDLK_LEFT: return Point(-1, 0);
|
||||
case SDLK_RIGHT: return Point(+1, 0);
|
||||
case SDLK_UP: return Point( 0, -1);
|
||||
|
||||
case SDLK_KP_1: return Point(-1, +1);
|
||||
case SDLK_KP_2: return Point( 0, +1);
|
||||
case SDLK_KP_3: return Point(+1, +1);
|
||||
case SDLK_KP_4: return Point(-1, 0);
|
||||
case SDLK_KP_5: return Point( 0, 0);
|
||||
case SDLK_KP_6: return Point(+1, 0);
|
||||
case SDLK_KP_7: return Point(-1, -1);
|
||||
case SDLK_KP_8: return Point( 0, -1);
|
||||
case SDLK_KP_9: return Point(+1, -1);
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
void CAdvMapInt::handleRightClick(std::string text, tribool down)
|
||||
{
|
||||
if(down)
|
||||
@ -972,7 +999,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
|
||||
heroList.redraw();
|
||||
}
|
||||
|
||||
void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
|
||||
void CAdvMapInt::mouseMoved( const Point & cursorPosition )
|
||||
{
|
||||
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
|
||||
if(swipeEnabled)
|
||||
@ -981,9 +1008,9 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
|
||||
// adventure map scrolling with mouse
|
||||
// currently disabled in world view mode (as it is in OH3), but should work correctly if mode check is removed
|
||||
// don't scroll if there is no window in focus - these events don't seem to correspond to the actual mouse movement
|
||||
if(!CSDL_Ext::isCtrlKeyDown() && isActive() && sEvent.windowID != 0 && mode == EAdvMapMode::NORMAL)
|
||||
if(!GH.isKeyboardCtrlDown() && isActive() && mode == EAdvMapMode::NORMAL)
|
||||
{
|
||||
if(sEvent.x<15)
|
||||
if(cursorPosition.x<15)
|
||||
{
|
||||
scrollingDir |= LEFT;
|
||||
}
|
||||
@ -991,7 +1018,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
|
||||
{
|
||||
scrollingDir &= ~LEFT;
|
||||
}
|
||||
if(sEvent.x>screen->w-15)
|
||||
if(cursorPosition.x > GH.screenDimensions().x - 15)
|
||||
{
|
||||
scrollingDir |= RIGHT;
|
||||
}
|
||||
@ -999,7 +1026,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
|
||||
{
|
||||
scrollingDir &= ~RIGHT;
|
||||
}
|
||||
if(sEvent.y<15)
|
||||
if(cursorPosition.y<15)
|
||||
{
|
||||
scrollingDir |= UP;
|
||||
}
|
||||
@ -1007,7 +1034,7 @@ void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
|
||||
{
|
||||
scrollingDir &= ~UP;
|
||||
}
|
||||
if(sEvent.y>screen->h-15)
|
||||
if(cursorPosition.y > GH.screenDimensions().y - 15)
|
||||
{
|
||||
scrollingDir |= DOWN;
|
||||
}
|
||||
@ -1246,7 +1273,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
||||
const CGPathNode * pathNode = LOCPLINT->cb->getPathsInfo(hero)->getPathInfo(mapPos);
|
||||
assert(pathNode);
|
||||
|
||||
if(LOCPLINT->altPressed() && pathNode->reachable()) //overwrite status bar text with movement info
|
||||
if(GH.isKeyboardAltDown() && pathNode->reachable()) //overwrite status bar text with movement info
|
||||
{
|
||||
ShowMoveDetailsInStatusbar(*hero, *pathNode);
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ class CAdvMapInt : public CIntObject
|
||||
//Return object that must be active at this tile (=clickable)
|
||||
const CGObjectInstance *getActiveObject(const int3 &tile);
|
||||
|
||||
boost::optional<Point> keyToMoveDirection(const SDL_Keycode & key);
|
||||
|
||||
public:
|
||||
CAdvMapInt();
|
||||
|
||||
@ -158,8 +160,9 @@ public:
|
||||
void centerOn(const CGObjectInstance *obj, bool fade = false);
|
||||
int3 verifyPos(int3 ver);
|
||||
void handleRightClick(std::string text, tribool down);
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyReleased(const SDL_Keycode & key) override;
|
||||
void mouseMoved (const Point & cursorPosition) override;
|
||||
bool isActive();
|
||||
|
||||
bool isHeroSleeping(const CGHeroInstance *hero);
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "CInGameConsole.h"
|
||||
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
@ -24,7 +24,6 @@
|
||||
#include "../../lib/mapObjects/CArmedInstance.h"
|
||||
|
||||
#include <SDL_timer.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
CInGameConsole::CInGameConsole()
|
||||
: CIntObject(KEYBOARD | TEXTINPUT),
|
||||
@ -91,13 +90,11 @@ void CInGameConsole::print(const std::string &txt)
|
||||
}
|
||||
}
|
||||
|
||||
void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
|
||||
void CInGameConsole::keyPressed (const SDL_Keycode & key)
|
||||
{
|
||||
if(key.type != SDL_KEYDOWN) return;
|
||||
if(!captureAllKeys && key != SDLK_TAB) return; //because user is not entering any text
|
||||
|
||||
if(!captureAllKeys && key.keysym.sym != SDLK_TAB) return; //because user is not entering any text
|
||||
|
||||
switch(key.keysym.sym)
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_TAB:
|
||||
case SDLK_ESCAPE:
|
||||
@ -106,7 +103,7 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
|
||||
{
|
||||
endEnteringText(false);
|
||||
}
|
||||
else if(SDLK_TAB == key.keysym.sym)
|
||||
else if(SDLK_TAB == key)
|
||||
{
|
||||
startEnteringText();
|
||||
}
|
||||
@ -178,19 +175,19 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
|
||||
}
|
||||
}
|
||||
|
||||
void CInGameConsole::textInputed(const SDL_TextInputEvent & event)
|
||||
void CInGameConsole::textInputed(const std::string & inputtedText)
|
||||
{
|
||||
if(!captureAllKeys || enteredText.size() == 0)
|
||||
return;
|
||||
enteredText.resize(enteredText.size()-1);
|
||||
|
||||
enteredText += event.text;
|
||||
enteredText += inputtedText;
|
||||
enteredText += "_";
|
||||
|
||||
refreshEnteredText();
|
||||
}
|
||||
|
||||
void CInGameConsole::textEdited(const SDL_TextEditingEvent & event)
|
||||
void CInGameConsole::textEdited(const std::string & inputtedText)
|
||||
{
|
||||
//do nothing here
|
||||
}
|
||||
|
@ -26,10 +26,10 @@ public:
|
||||
std::string enteredText;
|
||||
void show(SDL_Surface * to) override;
|
||||
void print(const std::string &txt);
|
||||
void keyPressed (const SDL_KeyboardEvent & key) override; //call-in
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
|
||||
void textInputed(const SDL_TextInputEvent & event) override;
|
||||
void textEdited(const SDL_TextEditingEvent & event) override;
|
||||
void textInputed(const std::string & enteredText) override;
|
||||
void textEdited(const std::string & enteredText) override;
|
||||
|
||||
void startEnteringText();
|
||||
void endEnteringText(bool processEnteredText);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../renderSDL/SDL_PixelAccess.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
@ -229,9 +230,9 @@ void CMinimap::hover(bool on)
|
||||
GH.statusbar->clear();
|
||||
}
|
||||
|
||||
void CMinimap::mouseMoved(const SDL_MouseMotionEvent & sEvent)
|
||||
void CMinimap::mouseMoved(const Point & cursorPosition)
|
||||
{
|
||||
if(mouseState(EIntObjMouseBtnType::LEFT))
|
||||
if(mouseState(MouseButton::LEFT))
|
||||
moveAdvMapSelection();
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ protected:
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
void hover (bool on) override;
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override;
|
||||
void mouseMoved (const Point & cursorPosition) override;
|
||||
|
||||
void moveAdvMapSelection();
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../widgets/Images.h"
|
||||
@ -44,8 +45,6 @@ CResDataBar::CResDataBar(const std::string & defname, int x, int y, int offx, in
|
||||
txtpos[i].second = pos.y + offy;
|
||||
}
|
||||
txtpos[7].first = txtpos[6].first + datedist;
|
||||
datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
|
||||
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
|
||||
addUsedEvents(RCLICK);
|
||||
}
|
||||
|
||||
@ -68,12 +67,23 @@ CResDataBar::CResDataBar()
|
||||
txtpos[i].second = pos.y + ADVOPT.resOffsetY;
|
||||
}
|
||||
txtpos[7].first = txtpos[6].first + ADVOPT.resDateDist;
|
||||
datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
|
||||
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
|
||||
|
||||
}
|
||||
|
||||
CResDataBar::~CResDataBar() = default;
|
||||
|
||||
std::string CResDataBar::buildDateString()
|
||||
{
|
||||
std::string pattern = "%s: %d, %s: %d, %s: %d";
|
||||
|
||||
auto formatted = boost::format(pattern)
|
||||
% CGI->generaltexth->translate("core.genrltxt.62") % LOCPLINT->cb->getDate(Date::MONTH)
|
||||
% CGI->generaltexth->translate("core.genrltxt.63") % LOCPLINT->cb->getDate(Date::WEEK)
|
||||
% CGI->generaltexth->translate("core.genrltxt.64") % LOCPLINT->cb->getDate(Date::DAY_OF_WEEK);
|
||||
|
||||
return boost::str(formatted);
|
||||
}
|
||||
|
||||
void CResDataBar::draw(SDL_Surface * to)
|
||||
{
|
||||
//TODO: all this should be labels, but they require proper text update on change
|
||||
@ -81,15 +91,9 @@ void CResDataBar::draw(SDL_Surface * to)
|
||||
{
|
||||
std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i));
|
||||
|
||||
graphics->fonts[FONT_SMALL]->renderTextLeft(to, text, Colors::WHITE, Point(txtpos[i].first,txtpos[i].second));
|
||||
graphics->fonts[FONT_SMALL]->renderTextLeft(to, text, Colors::WHITE, Point(txtpos[i].first, txtpos[i].second));
|
||||
}
|
||||
std::vector<std::string> temp;
|
||||
|
||||
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::MONTH)));
|
||||
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::WEEK)));
|
||||
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK)));
|
||||
|
||||
graphics->fonts[FONT_SMALL]->renderTextLeft(to, CSDL_Ext::processStr(datetext,temp), Colors::WHITE, Point(txtpos[7].first,txtpos[7].second));
|
||||
graphics->fonts[FONT_SMALL]->renderTextLeft(to, buildDateString(), Colors::WHITE, Point(txtpos[7].first, txtpos[7].second));
|
||||
}
|
||||
|
||||
void CResDataBar::show(SDL_Surface * to)
|
||||
|
@ -15,11 +15,12 @@
|
||||
/// Current date is displayed too
|
||||
class CResDataBar : public CIntObject
|
||||
{
|
||||
std::string buildDateString();
|
||||
|
||||
public:
|
||||
std::shared_ptr<CPicture> background;
|
||||
|
||||
std::vector<std::pair<int,int> > txtpos;
|
||||
std::string datetext;
|
||||
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
CResDataBar();
|
||||
|
@ -22,13 +22,14 @@
|
||||
#include "../render/IImage.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../CMT.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
#include "../../lib/CPathfinder.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_surface.h>
|
||||
|
||||
#define ADVOPT (conf.go()->ac)
|
||||
|
||||
@ -110,32 +111,31 @@ void CTerrainRect::clickMiddle(tribool down, bool previousState)
|
||||
handleSwipeStateChange((bool)down == true);
|
||||
}
|
||||
|
||||
void CTerrainRect::mouseMoved(const SDL_MouseMotionEvent & sEvent)
|
||||
void CTerrainRect::mouseMoved(const Point & cursorPosition)
|
||||
{
|
||||
handleHover(sEvent);
|
||||
handleHover(cursorPosition);
|
||||
|
||||
if(!adventureInt->swipeEnabled)
|
||||
return;
|
||||
|
||||
handleSwipeMove(sEvent);
|
||||
handleSwipeMove(cursorPosition);
|
||||
}
|
||||
|
||||
void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent)
|
||||
void CTerrainRect::handleSwipeMove(const Point & cursorPosition)
|
||||
{
|
||||
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
|
||||
if(sEvent.state == 0 || GH.multifinger) // any "button" is enough on mobile
|
||||
#else
|
||||
if((sEvent.state & SDL_BUTTON_MMASK) == 0) // swipe only works with middle mouse on other platforms
|
||||
#endif
|
||||
{
|
||||
if(!GH.isMouseButtonPressed() || GH.multifinger) // any "button" is enough on mobile
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if(!GH.isMouseButtonPressed(MouseButton::MIDDLE)) // swipe only works with middle mouse on other platforms
|
||||
return;
|
||||
#endif
|
||||
|
||||
if(!isSwiping)
|
||||
{
|
||||
// try to distinguish if this touch was meant to be a swipe or just fat-fingering press
|
||||
if(abs(sEvent.x - swipeInitialRealPos.x) > SwipeTouchSlop ||
|
||||
abs(sEvent.y - swipeInitialRealPos.y) > SwipeTouchSlop)
|
||||
if(abs(cursorPosition.x - swipeInitialRealPos.x) > SwipeTouchSlop ||
|
||||
abs(cursorPosition.y - swipeInitialRealPos.y) > SwipeTouchSlop)
|
||||
{
|
||||
isSwiping = true;
|
||||
}
|
||||
@ -144,9 +144,9 @@ void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent)
|
||||
if(isSwiping)
|
||||
{
|
||||
adventureInt->swipeTargetPosition.x =
|
||||
swipeInitialMapPos.x + static_cast<si32>(swipeInitialRealPos.x - sEvent.x) / 32;
|
||||
swipeInitialMapPos.x + static_cast<si32>(swipeInitialRealPos.x - cursorPosition.x) / 32;
|
||||
adventureInt->swipeTargetPosition.y =
|
||||
swipeInitialMapPos.y + static_cast<si32>(swipeInitialRealPos.y - sEvent.y) / 32;
|
||||
swipeInitialMapPos.y + static_cast<si32>(swipeInitialRealPos.y - cursorPosition.y) / 32;
|
||||
adventureInt->swipeMovementRequested = true;
|
||||
}
|
||||
}
|
||||
@ -155,7 +155,7 @@ bool CTerrainRect::handleSwipeStateChange(bool btnPressed)
|
||||
{
|
||||
if(btnPressed)
|
||||
{
|
||||
swipeInitialRealPos = int3(GH.getCursorPosition().x, GH.getCursorPosition().y, 0);
|
||||
swipeInitialRealPos = Point(GH.getCursorPosition().x, GH.getCursorPosition().y);
|
||||
swipeInitialMapPos = int3(adventureInt->position);
|
||||
return true;
|
||||
}
|
||||
@ -167,9 +167,9 @@ bool CTerrainRect::handleSwipeStateChange(bool btnPressed)
|
||||
return false;
|
||||
}
|
||||
|
||||
void CTerrainRect::handleHover(const SDL_MouseMotionEvent &sEvent)
|
||||
void CTerrainRect::handleHover(const Point & cursorPosition)
|
||||
{
|
||||
int3 tHovered = whichTileIsIt(sEvent.x, sEvent.y);
|
||||
int3 tHovered = whichTileIsIt(cursorPosition.x, cursorPosition.y);
|
||||
int3 pom = adventureInt->verifyPos(tHovered);
|
||||
|
||||
if(tHovered != pom) //tile outside the map
|
||||
@ -277,17 +277,17 @@ void CTerrainRect::showPath(const Rect & extRect, SDL_Surface * to)
|
||||
}
|
||||
else if(hvx<0)
|
||||
{
|
||||
Rect srcRect = CSDL_Ext::genRect(arrow->height() - hvy, arrow->width(), 0, 0);
|
||||
Rect srcRect (Point(0, 0), Point(arrow->height() - hvy, arrow->width()));
|
||||
arrow->draw(to, x + moveX, y + moveY, &srcRect);
|
||||
}
|
||||
else if (hvy<0)
|
||||
{
|
||||
Rect srcRect = CSDL_Ext::genRect(arrow->height(), arrow->width() - hvx, 0, 0);
|
||||
Rect srcRect (Point(0, 0), Point(arrow->height(), arrow->width() - hvx));
|
||||
arrow->draw(to, x + moveX, y + moveY, &srcRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect srcRect = CSDL_Ext::genRect(arrow->height() - hvy, arrow->width() - hvx, 0, 0);
|
||||
Rect srcRect (Point(0, 0), Point(arrow->height() - hvy, arrow->width() - hvx));
|
||||
arrow->draw(to, x + moveX, y + moveY, &srcRect);
|
||||
}
|
||||
}
|
||||
@ -299,17 +299,17 @@ void CTerrainRect::showPath(const Rect & extRect, SDL_Surface * to)
|
||||
}
|
||||
else if(hvx<0)
|
||||
{
|
||||
Rect srcRect = CSDL_Ext::genRect(arrow->height() - hvy, arrow->width(), 0, 0);
|
||||
Rect srcRect (Point(0, 0), Point(arrow->height() - hvy, arrow->width()));
|
||||
arrow->draw(to, x, y, &srcRect);
|
||||
}
|
||||
else if (hvy<0)
|
||||
{
|
||||
Rect srcRect = CSDL_Ext::genRect(arrow->height(), arrow->width() - hvx, 0, 0);
|
||||
Rect srcRect (Point(0, 0), Point(arrow->height(), arrow->width() - hvx));
|
||||
arrow->draw(to, x, y, &srcRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect srcRect = CSDL_Ext::genRect(arrow->height() - hvy, arrow->width() - hvx, 0, 0);
|
||||
Rect srcRect (Point(0, 0), Point(arrow->height() - hvy, arrow->width() - hvx));
|
||||
arrow->draw(to, x, y, &srcRect);
|
||||
}
|
||||
}
|
||||
|
@ -27,12 +27,12 @@ class CTerrainRect : public CIntObject
|
||||
std::shared_ptr<CFadeAnimation> fadeAnim;
|
||||
|
||||
int3 swipeInitialMapPos;
|
||||
int3 swipeInitialRealPos;
|
||||
Point swipeInitialRealPos;
|
||||
bool isSwiping;
|
||||
static constexpr float SwipeTouchSlop = 16.0f;
|
||||
|
||||
void handleHover(const SDL_MouseMotionEvent & sEvent);
|
||||
void handleSwipeMove(const SDL_MouseMotionEvent & sEvent);
|
||||
void handleHover(const Point & cursorPosition);
|
||||
void handleSwipeMove(const Point & cursorPosition);
|
||||
/// handles start/finish of swipe (press/release of corresponding button); returns true if state change was handled
|
||||
bool handleSwipeStateChange(bool btnPressed);
|
||||
public:
|
||||
@ -48,7 +48,7 @@ public:
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
void clickMiddle(tribool down, bool previousState) override;
|
||||
void hover(bool on) override;
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override;
|
||||
void mouseMoved (const Point & cursorPosition) override;
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
void showAnim(SDL_Surface * to);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../render/CFadeAnimation.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../CGameInfo.h"
|
||||
#include "../render/Graphics.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,10 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class BattleAction;
|
||||
namespace spells {
|
||||
class Caster;
|
||||
enum class Mode;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
@ -34,65 +38,87 @@ class BattleActionsController
|
||||
/// all actions possible to call at the moment by player
|
||||
std::vector<PossiblePlayerBattleAction> possibleActions;
|
||||
|
||||
/// actions possible to take on hovered hex
|
||||
std::vector<PossiblePlayerBattleAction> localActions;
|
||||
|
||||
/// these actions display message in case of illegal target
|
||||
std::vector<PossiblePlayerBattleAction> illegalActions;
|
||||
|
||||
/// action that will be performed on l-click
|
||||
PossiblePlayerBattleAction currentAction;
|
||||
|
||||
/// last action chosen (and saved) by player
|
||||
PossiblePlayerBattleAction selectedAction;
|
||||
|
||||
/// if there are not possible actions to choose from, this action should be show as "illegal" in UI
|
||||
PossiblePlayerBattleAction illegalAction;
|
||||
|
||||
/// if true, stack currently aims to cats a spell
|
||||
bool creatureCasting;
|
||||
|
||||
/// if true, player is choosing destination for his spell - only for GUI / console
|
||||
bool spellDestSelectMode;
|
||||
|
||||
/// spell for which player is choosing destination
|
||||
std::shared_ptr<BattleAction> spellToCast;
|
||||
|
||||
/// spell for which player is choosing destination, pointer for convenience
|
||||
const CSpell *currentSpell;
|
||||
/// spell for which player's hero is choosing destination
|
||||
std::shared_ptr<BattleAction> heroSpellToCast;
|
||||
|
||||
/// cached message that was set by this class in status bar
|
||||
std::string currentConsoleMsg;
|
||||
|
||||
/// if true, active stack could possibly cast some target spell
|
||||
const CSpell * creatureSpellToCast;
|
||||
|
||||
bool isCastingPossibleHere (const CStack *sactive, const CStack *shere, BattleHex myNumber);
|
||||
bool canStackMoveHere (const CStack *sactive, BattleHex MyNumber) const; //TODO: move to BattleState / callback
|
||||
std::vector<PossiblePlayerBattleAction> getPossibleActionsForStack (const CStack *stack) const; //called when stack gets its turn
|
||||
void reorderPossibleActionsPriority(const CStack * stack, MouseHoveredHexContext context);
|
||||
|
||||
bool actionIsLegal(PossiblePlayerBattleAction action, BattleHex hoveredHex);
|
||||
|
||||
void actionSetCursor(PossiblePlayerBattleAction action, BattleHex hoveredHex);
|
||||
void actionSetCursorBlocked(PossiblePlayerBattleAction action, BattleHex hoveredHex);
|
||||
|
||||
std::string actionGetStatusMessage(PossiblePlayerBattleAction action, BattleHex hoveredHex);
|
||||
std::string actionGetStatusMessageBlocked(PossiblePlayerBattleAction action, BattleHex hoveredHex);
|
||||
|
||||
void actionRealize(PossiblePlayerBattleAction action, BattleHex hoveredHex);
|
||||
|
||||
PossiblePlayerBattleAction selectAction(BattleHex myNumber);
|
||||
|
||||
const CStack * getStackForHex(BattleHex myNumber) ;
|
||||
|
||||
/// attempts to initialize spellcasting action for stack
|
||||
/// will silently return if stack is not a spellcaster
|
||||
void tryActivateStackSpellcasting(const CStack *casterStack);
|
||||
|
||||
/// returns spell that is currently being cast by hero or nullptr if none
|
||||
const CSpell * getHeroSpellToCast() const;
|
||||
|
||||
/// if current stack is spellcaster, returns spell being cast, or null othervice
|
||||
const CSpell * getStackSpellToCast( ) const;
|
||||
|
||||
/// returns true if current stack is a spellcaster
|
||||
bool isActiveStackSpellcaster() const;
|
||||
|
||||
public:
|
||||
BattleActionsController(BattleInterface & owner);
|
||||
|
||||
/// initialize list of potential actions for new active stack
|
||||
void activateStack();
|
||||
|
||||
/// initialize potential actions for spells that can be cast by active stack
|
||||
/// returns true if UI is currently in target selection mode
|
||||
bool spellcastingModeActive() const;
|
||||
|
||||
/// returns true if one of the following is true:
|
||||
/// - we are casting spell by hero
|
||||
/// - we are casting spell by creature in targeted mode (F hotkey)
|
||||
/// - current creature is spellcaster and preferred action for current hex is spellcast
|
||||
bool currentActionSpellcasting(BattleHex hoveredHex);
|
||||
|
||||
/// enter targeted spellcasting mode for creature, e.g. via "F" hotkey
|
||||
void enterCreatureCastingMode();
|
||||
|
||||
/// initialize potential actions for selected spell
|
||||
/// initialize hero spellcasting mode, e.g. on selecting spell in spellbook
|
||||
void castThisSpell(SpellID spellID);
|
||||
|
||||
/// ends casting spell (eg. when spell has been cast or canceled)
|
||||
void endCastingSpell();
|
||||
|
||||
/// update UI (e.g. status bar/cursor) according to new active hex
|
||||
void handleHex(BattleHex myNumber, int eventType);
|
||||
/// update cursor and status bar according to new active hex
|
||||
void onHexHovered(BattleHex hoveredHex);
|
||||
|
||||
/// returns currently selected spell or SpellID::NONE on error
|
||||
SpellID selectedSpell() const;
|
||||
/// called when cursor is no longer over battlefield and cursor/battle log should be reset
|
||||
void onHoverEnded();
|
||||
|
||||
/// performs action according to selected hex
|
||||
void onHexLeftClicked(BattleHex clickedHex);
|
||||
|
||||
/// performs action according to selected hex
|
||||
void onHexRightClicked(BattleHex clickedHex);
|
||||
|
||||
const spells::Caster * getCurrentSpellcaster() const;
|
||||
const CSpell * getCurrentSpell() const;
|
||||
spells::Mode getCurrentCastMode() const;
|
||||
|
||||
/// returns true if UI is currently in target selection mode
|
||||
bool spellcastingModeActive() const;
|
||||
|
||||
/// methods to work with array of possible actions, needed to control special creatures abilities
|
||||
const std::vector<PossiblePlayerBattleAction> & getPossibleActions() const;
|
||||
void removePossibleAction(PossiblePlayerBattleAction);
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "../../lib/CStack.h"
|
||||
#include "../../lib/spells/ISpellMechanics.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
BattleFieldController::BattleFieldController(BattleInterface & owner):
|
||||
owner(owner)
|
||||
{
|
||||
@ -76,20 +78,11 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
|
||||
|
||||
backgroundWithHexes = std::make_unique<Canvas>(Point(background->width(), background->height()));
|
||||
|
||||
for (int h = 0; h < GameConstants::BFIELD_SIZE; ++h)
|
||||
{
|
||||
auto hex = std::make_shared<ClickableHex>();
|
||||
hex->myNumber = h;
|
||||
hex->pos = hexPositionAbsolute(h);
|
||||
hex->myInterface = &owner;
|
||||
bfield.push_back(hex);
|
||||
}
|
||||
|
||||
auto accessibility = owner.curInt->cb->getAccesibility();
|
||||
for(int i = 0; i < accessibility.size(); i++)
|
||||
stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
|
||||
|
||||
addUsedEvents(MOVE);
|
||||
addUsedEvents(LCLICK | RCLICK | MOVE);
|
||||
LOCPLINT->cingconsole->pos = this->pos;
|
||||
}
|
||||
|
||||
@ -105,13 +98,40 @@ void BattleFieldController::createHeroes()
|
||||
owner.defendingHero = std::make_shared<BattleHero>(owner, owner.defendingHeroInstance, true);
|
||||
}
|
||||
|
||||
void BattleFieldController::mouseMoved(const SDL_MouseMotionEvent &event)
|
||||
void BattleFieldController::mouseMoved(const Point & cursorPosition)
|
||||
{
|
||||
BattleHex selectedHex = getHoveredHex();
|
||||
if (!pos.isInside(cursorPosition))
|
||||
{
|
||||
owner.actionsController->onHoverEnded();
|
||||
return;
|
||||
}
|
||||
|
||||
owner.actionsController->handleHex(selectedHex, MOVE);
|
||||
BattleHex selectedHex = getHoveredHex();
|
||||
owner.actionsController->onHexHovered(selectedHex);
|
||||
}
|
||||
|
||||
void BattleFieldController::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if(!down)
|
||||
{
|
||||
BattleHex selectedHex = getHoveredHex();
|
||||
|
||||
if (selectedHex != BattleHex::INVALID)
|
||||
owner.actionsController->onHexLeftClicked(selectedHex);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleFieldController::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down)
|
||||
{
|
||||
BattleHex selectedHex = getHoveredHex();
|
||||
|
||||
if (selectedHex != BattleHex::INVALID)
|
||||
owner.actionsController->onHexRightClicked(selectedHex);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void BattleFieldController::renderBattlefield(Canvas & canvas)
|
||||
{
|
||||
@ -233,19 +253,9 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
|
||||
const spells::Caster *caster = nullptr;
|
||||
const CSpell *spell = nullptr;
|
||||
|
||||
spells::Mode mode = spells::Mode::HERO;
|
||||
|
||||
if(owner.actionsController->spellcastingModeActive())//hero casts spell
|
||||
{
|
||||
spell = owner.actionsController->selectedSpell().toSpell();
|
||||
caster = owner.getActiveHero();
|
||||
}
|
||||
else if(owner.stacksController->activeStackSpellToCast() != SpellID::NONE)//stack casts spell
|
||||
{
|
||||
spell = SpellID(owner.stacksController->activeStackSpellToCast()).toSpell();
|
||||
caster = owner.stacksController->getActiveStack();
|
||||
mode = spells::Mode::CREATURE_ACTIVE;
|
||||
}
|
||||
spells::Mode mode = owner.actionsController->getCurrentCastMode();
|
||||
spell = owner.actionsController->getCurrentSpell();
|
||||
caster = owner.actionsController->getCurrentSpellcaster();
|
||||
|
||||
if(caster && spell) //when casting spell
|
||||
{
|
||||
@ -310,7 +320,10 @@ void BattleFieldController::showHighlightedHexes(Canvas & canvas)
|
||||
std::set<BattleHex> hoveredSpell = getHighlightedHexesSpellRange();
|
||||
std::set<BattleHex> hoveredMove = getHighlightedHexesMovementTarget();
|
||||
|
||||
auto const & hoveredMouse = owner.actionsController->spellcastingModeActive() ? hoveredSpell : hoveredMove;
|
||||
if (getHoveredHex() == BattleHex::INVALID)
|
||||
return;
|
||||
|
||||
auto const & hoveredMouse = owner.actionsController->currentActionSpellcasting(getHoveredHex()) ? hoveredSpell : hoveredMove;
|
||||
|
||||
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
||||
{
|
||||
@ -355,9 +368,31 @@ bool BattleFieldController::isPixelInHex(Point const & position)
|
||||
|
||||
BattleHex BattleFieldController::getHoveredHex()
|
||||
{
|
||||
for ( auto const & hex : bfield)
|
||||
if (hex->hovered && hex->strictHovered)
|
||||
return hex->myNumber;
|
||||
Point hoverPos = GH.getCursorPosition();
|
||||
|
||||
if (owner.attackingHero)
|
||||
{
|
||||
if (owner.attackingHero->pos.isInside(hoverPos))
|
||||
return BattleHex::HERO_ATTACKER;
|
||||
}
|
||||
|
||||
if (owner.defendingHero)
|
||||
{
|
||||
if (owner.attackingHero->pos.isInside(hoverPos))
|
||||
return BattleHex::HERO_DEFENDER;
|
||||
}
|
||||
|
||||
|
||||
for (int h = 0; h < GameConstants::BFIELD_SIZE; ++h)
|
||||
{
|
||||
Rect hexPosition = hexPositionAbsolute(h);
|
||||
|
||||
if (!hexPosition.isInside(hoverPos))
|
||||
continue;
|
||||
|
||||
if (isPixelInHex(hoverPos - hexPosition.topLeft()))
|
||||
return h;
|
||||
}
|
||||
|
||||
return BattleHex::INVALID;
|
||||
}
|
||||
@ -520,7 +555,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex attackTarget)
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
return attackTarget.cloneInDirection(BattleHex::LEFT);
|
||||
return BattleHex::INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ class Point;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class ClickableHex;
|
||||
class BattleHero;
|
||||
class Canvas;
|
||||
class IImage;
|
||||
@ -50,8 +49,6 @@ class BattleFieldController : public CIntObject
|
||||
/// hexes that when in front of a unit cause it's amount box to move back
|
||||
std::array<bool, GameConstants::BFIELD_SIZE> stackCountOutsideHexes;
|
||||
|
||||
std::vector<std::shared_ptr<ClickableHex>> bfield;
|
||||
|
||||
void showHighlightedHex(Canvas & to, BattleHex hex, bool darkBorder);
|
||||
|
||||
std::set<BattleHex> getHighlightedHexesStackRange();
|
||||
@ -65,10 +62,12 @@ class BattleFieldController : public CIntObject
|
||||
|
||||
BattleHex::EDir selectAttackDirection(BattleHex myNumber, const Point & point);
|
||||
|
||||
void mouseMoved(const SDL_MouseMotionEvent &event) override;
|
||||
void mouseMoved(const Point & cursorPosition) override;
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
|
||||
void showAll(SDL_Surface * to) override;
|
||||
void show(SDL_Surface * to) override;
|
||||
|
||||
public:
|
||||
BattleFieldController(BattleInterface & owner);
|
||||
|
||||
|
@ -54,7 +54,6 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
|
||||
, attackerInt(att)
|
||||
, defenderInt(defen)
|
||||
, curInt(att)
|
||||
, myTurn(false)
|
||||
, moveSoundHander(-1)
|
||||
{
|
||||
for ( auto & event : animationEvents)
|
||||
@ -249,7 +248,6 @@ void BattleInterface::sendCommand(BattleAction *& command, const CStack * actor)
|
||||
if(!tacticsMode)
|
||||
{
|
||||
logGlobal->trace("Setting command for %s", (actor ? actor->nodeName() : "hero"));
|
||||
myTurn = false;
|
||||
stacksController->setActiveStack(nullptr);
|
||||
givenCommand.setn(command);
|
||||
}
|
||||
@ -260,6 +258,7 @@ void BattleInterface::sendCommand(BattleAction *& command, const CStack * actor)
|
||||
stacksController->setActiveStack(nullptr);
|
||||
//next stack will be activated when action ends
|
||||
}
|
||||
CCS->curh->set(Cursor::Combat::POINTER);
|
||||
}
|
||||
|
||||
const CGHeroInstance * BattleInterface::getActiveHero()
|
||||
@ -499,7 +498,6 @@ void BattleInterface::displaySpellHit(const CSpell * spell, BattleHex destinatio
|
||||
displaySpellAnimationQueue(spell, spell->animationInfo.hit, destinationTile, true);
|
||||
}
|
||||
|
||||
|
||||
CPlayerInterface *BattleInterface::getCurrentPlayerInterface() const
|
||||
{
|
||||
return curInt.get();
|
||||
@ -522,7 +520,6 @@ void BattleInterface::activateStack()
|
||||
if(!s)
|
||||
return;
|
||||
|
||||
myTurn = true;
|
||||
windowObject->updateQueue();
|
||||
windowObject->blockUI(false);
|
||||
fieldController->redrawBackgroundWithHexes();
|
||||
@ -530,6 +527,11 @@ void BattleInterface::activateStack()
|
||||
GH.fakeMouseMove();
|
||||
}
|
||||
|
||||
bool BattleInterface::makingTurn() const
|
||||
{
|
||||
return stacksController->getActiveStack() != nullptr;
|
||||
}
|
||||
|
||||
void BattleInterface::endAction(const BattleAction* action)
|
||||
{
|
||||
const CStack *stack = curInt->cb->battleGetStackByID(action->stackNumber);
|
||||
|
@ -37,7 +37,6 @@ class Canvas;
|
||||
class BattleResultWindow;
|
||||
class StackQueue;
|
||||
class CPlayerInterface;
|
||||
class ClickableHex;
|
||||
class CAnimation;
|
||||
struct BattleEffect;
|
||||
class IImage;
|
||||
@ -146,7 +145,8 @@ public:
|
||||
|
||||
static CondSh<BattleAction *> givenCommand; //data != nullptr if we have i.e. moved current unit
|
||||
|
||||
bool myTurn; //if true, interface is active (commands can be ordered)
|
||||
bool makingTurn() const;
|
||||
|
||||
int moveSoundHander; // sound handler used when moving a unit
|
||||
|
||||
BattleInterface(const CCreatureSet *army1, const CCreatureSet *army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt = nullptr);
|
||||
|
@ -30,10 +30,10 @@
|
||||
#include "../widgets/Images.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../windows/CCreatureWindow.h"
|
||||
#include "../windows/CSpellWindow.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../adventureMap/CInGameConsole.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CStack.h"
|
||||
@ -48,9 +48,6 @@
|
||||
#include "../../lib/CondSh.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
|
||||
#include <SDL_surface.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
void BattleConsole::showAll(SDL_Surface * to)
|
||||
{
|
||||
CIntObject::showAll(to);
|
||||
@ -163,12 +160,12 @@ void BattleConsole::setEnteringMode(bool on)
|
||||
if (on)
|
||||
{
|
||||
assert(enteringText == false);
|
||||
CSDL_Ext::startTextInput(pos);
|
||||
GH.startTextInput(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(enteringText == true);
|
||||
CSDL_Ext::stopTextInput();
|
||||
GH.stopTextInput();
|
||||
}
|
||||
enteringText = on;
|
||||
redraw();
|
||||
@ -274,50 +271,29 @@ void BattleHero::setPhase(EHeroAnimType newPhase)
|
||||
nextPhase = EHeroAnimType::HOLDING;
|
||||
}
|
||||
|
||||
void BattleHero::hover(bool on)
|
||||
{
|
||||
//TODO: BROKEN CODE
|
||||
if (on)
|
||||
CCS->curh->set(Cursor::Combat::HERO);
|
||||
else
|
||||
CCS->curh->set(Cursor::Combat::POINTER);
|
||||
}
|
||||
|
||||
void BattleHero::clickLeft(tribool down, bool previousState)
|
||||
void BattleHero::heroLeftClicked()
|
||||
{
|
||||
if(owner.actionsController->spellcastingModeActive()) //we are casting a spell
|
||||
return;
|
||||
|
||||
if(boost::logic::indeterminate(down))
|
||||
return;
|
||||
|
||||
if(!hero || down || !owner.myTurn)
|
||||
if(!hero || !owner.makingTurn())
|
||||
return;
|
||||
|
||||
if(owner.getCurrentPlayerInterface()->cb->battleCanCastSpell(hero, spells::Mode::HERO) == ESpellCastProblem::OK) //check conditions
|
||||
{
|
||||
BattleHex hoveredHex = owner.fieldController->getHoveredHex();
|
||||
//do nothing when any hex is hovered - hero's animation overlaps battlefield
|
||||
if ( hoveredHex != BattleHex::INVALID )
|
||||
return;
|
||||
|
||||
CCS->curh->set(Cursor::Map::POINTER);
|
||||
|
||||
GH.pushIntT<CSpellWindow>(hero, owner.getCurrentPlayerInterface());
|
||||
}
|
||||
}
|
||||
|
||||
void BattleHero::clickRight(tribool down, bool previousState)
|
||||
void BattleHero::heroRightClicked()
|
||||
{
|
||||
if(boost::logic::indeterminate(down))
|
||||
return;
|
||||
|
||||
Point windowPosition;
|
||||
windowPosition.x = (!defender) ? owner.fieldController->pos.left() + 1 : owner.fieldController->pos.right() - 79;
|
||||
windowPosition.y = owner.fieldController->pos.y + 135;
|
||||
|
||||
InfoAboutHero targetHero;
|
||||
if(down && (owner.myTurn || settings["session"]["spectate"].Bool()))
|
||||
if(owner.makingTurn() || settings["session"]["spectate"].Bool())
|
||||
{
|
||||
auto h = defender ? owner.defendingHeroInstance : owner.attackingHeroInstance;
|
||||
targetHero.initFromHero(h, InfoAboutHero::EInfoLevel::INBATTLE);
|
||||
@ -374,8 +350,6 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
|
||||
flagAnimation->preload();
|
||||
flagAnimation->playerColored(hero->tempOwner);
|
||||
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||
|
||||
switchToNextPhase();
|
||||
play();
|
||||
}
|
||||
@ -427,9 +401,9 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
pos = CSDL_Ext::genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19);
|
||||
background = std::make_shared<CPicture>("CPRESULT");
|
||||
background->colorize(owner.playerID);
|
||||
pos = center(background->pos);
|
||||
|
||||
exit = std::make_shared<CButton>(Point(384, 505), "iok6432.def", std::make_pair("", ""), [&](){ bExitf();}, SDLK_RETURN);
|
||||
exit->setBorderColor(Colors::METALLIC_GOLD);
|
||||
@ -591,7 +565,7 @@ void BattleResultWindow::activate()
|
||||
void BattleResultWindow::show(SDL_Surface * to)
|
||||
{
|
||||
CIntObject::show(to);
|
||||
CCS->videoh->update(pos.x + 107, pos.y + 70, screen, true, false);
|
||||
CCS->videoh->update(pos.x + 107, pos.y + 70, to, true, false);
|
||||
}
|
||||
|
||||
void BattleResultWindow::bExitf()
|
||||
@ -609,68 +583,6 @@ void BattleResultWindow::bExitf()
|
||||
CCS->videoh->close();
|
||||
}
|
||||
|
||||
void ClickableHex::hover(bool on)
|
||||
{
|
||||
hovered = on;
|
||||
//Hoverable::hover(on);
|
||||
if(!on && setAlterText)
|
||||
{
|
||||
GH.statusbar->clear();
|
||||
setAlterText = false;
|
||||
}
|
||||
}
|
||||
|
||||
ClickableHex::ClickableHex() : setAlterText(false), myNumber(-1), strictHovered(false), myInterface(nullptr)
|
||||
{
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER | MOVE);
|
||||
}
|
||||
|
||||
void ClickableHex::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||
{
|
||||
strictHovered = myInterface->fieldController->isPixelInHex(Point(sEvent.x-pos.x, sEvent.y-pos.y));
|
||||
|
||||
if(hovered && strictHovered) //print attacked creature to console
|
||||
{
|
||||
const CStack * attackedStack = myInterface->getCurrentPlayerInterface()->cb->battleGetStackByPos(myNumber);
|
||||
if( attackedStack != nullptr &&
|
||||
attackedStack->owner != myInterface->getCurrentPlayerInterface()->playerID &&
|
||||
attackedStack->alive())
|
||||
{
|
||||
MetaString text;
|
||||
text.addTxt(MetaString::GENERAL_TXT, 220);
|
||||
attackedStack->addNameReplacement(text);
|
||||
GH.statusbar->write(text.toString());
|
||||
setAlterText = true;
|
||||
}
|
||||
}
|
||||
else if(setAlterText)
|
||||
{
|
||||
GH.statusbar->clear();
|
||||
setAlterText = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ClickableHex::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if(!down && hovered && strictHovered) //we've been really clicked!
|
||||
{
|
||||
myInterface->actionsController->handleHex(myNumber, LCLICK);
|
||||
}
|
||||
}
|
||||
|
||||
void ClickableHex::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
const CStack * myst = myInterface->getCurrentPlayerInterface()->cb->battleGetStackByPos(myNumber); //stack info
|
||||
if(hovered && strictHovered && myst!=nullptr)
|
||||
{
|
||||
if(!myst->alive()) return;
|
||||
if(down)
|
||||
{
|
||||
GH.pushIntT<CStackWindow>(myst, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackQueue::StackQueue(bool Embedded, BattleInterface & owner)
|
||||
: embedded(Embedded),
|
||||
owner(owner)
|
||||
@ -712,6 +624,14 @@ StackQueue::StackQueue(bool Embedded, BattleInterface & owner)
|
||||
|
||||
void StackQueue::show(SDL_Surface * to)
|
||||
{
|
||||
auto unitIdsToHighlight = owner.stacksController->getHoveredStacksUnitIds();
|
||||
|
||||
for(auto & stackBox : stackBoxes)
|
||||
{
|
||||
bool isBoundUnitCurrentlyHovered = vstd::contains(unitIdsToHighlight, stackBox->getBoundUnitID());
|
||||
stackBox->toggleHighlight(isBoundUnitCurrentlyHovered);
|
||||
}
|
||||
|
||||
if (embedded)
|
||||
showAll(to);
|
||||
CIntObject::show(to);
|
||||
@ -740,8 +660,21 @@ int32_t StackQueue::getSiegeShooterIconID()
|
||||
return owner.siegeController->getSiegedTown()->town->faction->getIndex();
|
||||
}
|
||||
|
||||
boost::optional<uint32_t> StackQueue::getHoveredUnitIdIfAny() const
|
||||
{
|
||||
for(const auto & stackBox : stackBoxes)
|
||||
{
|
||||
if(stackBox->hovered || stackBox->mouseState(MouseButton::RIGHT))
|
||||
{
|
||||
return stackBox->getBoundUnitID();
|
||||
}
|
||||
}
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
StackQueue::StackBox::StackBox(StackQueue * owner):
|
||||
owner(owner)
|
||||
CIntObject(RCLICK | HOVER), owner(owner)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
background = std::make_shared<CPicture>(owner->embedded ? "StackQueueSmall" : "StackQueueLarge");
|
||||
@ -771,6 +704,7 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
|
||||
{
|
||||
if(unit)
|
||||
{
|
||||
boundUnitID = unit->unitId();
|
||||
background->colorize(unit->unitOwner());
|
||||
icon->visible = true;
|
||||
|
||||
@ -783,7 +717,7 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
|
||||
if (unit->unitType()->idNumber == CreatureID::ARROW_TOWERS)
|
||||
icon->setFrame(owner->getSiegeShooterIconID(), 1);
|
||||
|
||||
amount->setText(CSDL_Ext::makeNumberShort(unit->getCount(), 4));
|
||||
amount->setText(vstd::formatMetric(unit->getCount(), 4));
|
||||
|
||||
if(stateIcon)
|
||||
{
|
||||
@ -805,6 +739,7 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
|
||||
}
|
||||
else
|
||||
{
|
||||
boundUnitID = boost::none;
|
||||
background->colorize(PlayerColor::NEUTRAL);
|
||||
icon->visible = false;
|
||||
icon->setFrame(0);
|
||||
@ -814,3 +749,21 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
|
||||
stateIcon->visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
boost::optional<uint32_t> StackQueue::StackBox::getBoundUnitID() const
|
||||
{
|
||||
return boundUnitID;
|
||||
}
|
||||
|
||||
void StackQueue::StackBox::toggleHighlight(bool value)
|
||||
{
|
||||
highlighted = value;
|
||||
}
|
||||
|
||||
void StackQueue::StackBox::show(SDL_Surface *to)
|
||||
{
|
||||
if(highlighted)
|
||||
CSDL_Ext::drawBorder(to, background->pos.x, background->pos.y, background->pos.w, background->pos.h, { 0, 255, 255, 255 }, 2);
|
||||
|
||||
CIntObject::show(to);
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ public:
|
||||
void pause();
|
||||
void play();
|
||||
|
||||
void hover(bool on) override;
|
||||
void clickLeft(tribool down, bool previousState) override; //call-in
|
||||
void clickRight(tribool down, bool previousState) override; //call-in
|
||||
void heroLeftClicked();
|
||||
void heroRightClicked();
|
||||
|
||||
BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender);
|
||||
};
|
||||
|
||||
@ -157,38 +157,27 @@ public:
|
||||
void show(SDL_Surface * to = 0) override;
|
||||
};
|
||||
|
||||
/// Class which stands for a single hex field on a battlefield
|
||||
class ClickableHex : public CIntObject
|
||||
{
|
||||
private:
|
||||
bool setAlterText; //if true, this hex has set alternative text in console and will clean it
|
||||
public:
|
||||
ui32 myNumber; //number of hex in commonly used format
|
||||
bool strictHovered; //for determining if hex is hovered by mouse (this is different problem than hex's graphic hovering)
|
||||
BattleInterface * myInterface; //interface that owns me
|
||||
|
||||
//for user interactions
|
||||
void hover (bool on) override;
|
||||
void mouseMoved (const SDL_MouseMotionEvent &sEvent) override;
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
ClickableHex();
|
||||
};
|
||||
|
||||
/// Shows the stack queue
|
||||
class StackQueue : public CIntObject
|
||||
{
|
||||
class StackBox : public CIntObject
|
||||
{
|
||||
StackQueue * owner;
|
||||
boost::optional<uint32_t> boundUnitID;
|
||||
bool highlighted = false;
|
||||
|
||||
public:
|
||||
std::shared_ptr<CPicture> background;
|
||||
std::shared_ptr<CAnimImage> icon;
|
||||
std::shared_ptr<CLabel> amount;
|
||||
std::shared_ptr<CAnimImage> stateIcon;
|
||||
|
||||
void setUnit(const battle::Unit * unit, size_t turn = 0);
|
||||
StackBox(StackQueue * owner);
|
||||
void setUnit(const battle::Unit * unit, size_t turn = 0);
|
||||
void toggleHighlight(bool value);
|
||||
boost::optional<uint32_t> getBoundUnitID() const;
|
||||
|
||||
void show(SDL_Surface * to) override;
|
||||
};
|
||||
|
||||
static const int QUEUE_SIZE = 10;
|
||||
@ -205,6 +194,7 @@ public:
|
||||
|
||||
StackQueue(bool Embedded, BattleInterface & owner);
|
||||
void update();
|
||||
boost::optional<uint32_t> getHoveredUnitIdIfAny() const;
|
||||
|
||||
void show(SDL_Surface * to) override;
|
||||
};
|
||||
|
@ -26,8 +26,9 @@
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../CGameInfo.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/spells/ISpellMechanics.h"
|
||||
@ -73,8 +74,6 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
|
||||
activeStack(nullptr),
|
||||
stackToActivate(nullptr),
|
||||
selectedStack(nullptr),
|
||||
stackCanCastSpell(false),
|
||||
creatureSpellToCast(uint32_t(-1)),
|
||||
animIDhelper(0)
|
||||
{
|
||||
//preparing graphics for displaying amounts of creatures
|
||||
@ -317,7 +316,7 @@ void BattleStacksController::showStackAmountBox(Canvas & canvas, const CStack *
|
||||
//blitting amount
|
||||
Point textPos = stackAnimation[stack->ID]->pos.topLeft() + amountBG->dimensions()/2 + Point(xAdd, yAdd);
|
||||
|
||||
canvas.drawText(textPos, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::CENTER, CSDL_Ext::makeNumberShort(stack->getCount(), 4));
|
||||
canvas.drawText(textPos, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::CENTER, vstd::formatMetric(stack->getCount(), 4));
|
||||
}
|
||||
|
||||
void BattleStacksController::showStack(Canvas & canvas, const CStack * stack)
|
||||
@ -738,25 +737,6 @@ void BattleStacksController::activateStack()
|
||||
const CStack * s = getActiveStack();
|
||||
if(!s)
|
||||
return;
|
||||
|
||||
//set casting flag to true if creature can use it to not check it every time
|
||||
const auto spellcaster = s->getBonusLocalFirst(Selector::type()(Bonus::SPELLCASTER));
|
||||
const auto randomSpellcaster = s->getBonusLocalFirst(Selector::type()(Bonus::RANDOM_SPELLCASTER));
|
||||
if(s->canCast() && (spellcaster || randomSpellcaster))
|
||||
{
|
||||
stackCanCastSpell = true;
|
||||
if(randomSpellcaster)
|
||||
creatureSpellToCast = -1; //spell will be set later on cast
|
||||
else
|
||||
creatureSpellToCast = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), s, CBattleInfoCallback::RANDOM_AIMED); //faerie dragon can cast only one spell until their next move
|
||||
//TODO: what if creature can cast BOTH random genie spell and aimed spell?
|
||||
//TODO: faerie dragon type spell should be selected by server
|
||||
}
|
||||
else
|
||||
{
|
||||
stackCanCastSpell = false;
|
||||
creatureSpellToCast = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleStacksController::setSelectedStack(const CStack *stack)
|
||||
@ -779,18 +759,6 @@ bool BattleStacksController::facingRight(const CStack * stack) const
|
||||
return stackFacingRight.at(stack->ID);
|
||||
}
|
||||
|
||||
bool BattleStacksController::activeStackSpellcaster()
|
||||
{
|
||||
return stackCanCastSpell;
|
||||
}
|
||||
|
||||
SpellID BattleStacksController::activeStackSpellToCast()
|
||||
{
|
||||
if (!stackCanCastSpell)
|
||||
return SpellID::NONE;
|
||||
return SpellID(creatureSpellToCast);
|
||||
}
|
||||
|
||||
Point BattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CStack * stack) const
|
||||
{
|
||||
Point ret(-500, -500); //returned value
|
||||
@ -896,6 +864,12 @@ std::vector<const CStack *> BattleStacksController::selectHoveredStacks()
|
||||
if(owner.getAnimationCondition(EAnimationEvents::ACTION) == true)
|
||||
return {};
|
||||
|
||||
auto hoveredQueueUnitId = owner.windowObject->getQueueHoveredUnitId();
|
||||
if(hoveredQueueUnitId.is_initialized())
|
||||
{
|
||||
return { owner.curInt->cb->battleGetStackByID(hoveredQueueUnitId.value(), true) };
|
||||
}
|
||||
|
||||
auto hoveredHex = owner.fieldController->getHoveredHex();
|
||||
|
||||
if (!hoveredHex.isValid())
|
||||
@ -904,21 +878,11 @@ std::vector<const CStack *> BattleStacksController::selectHoveredStacks()
|
||||
const spells::Caster *caster = nullptr;
|
||||
const CSpell *spell = nullptr;
|
||||
|
||||
spells::Mode mode = spells::Mode::HERO;
|
||||
spells::Mode mode = owner.actionsController->getCurrentCastMode();
|
||||
spell = owner.actionsController->getCurrentSpell();
|
||||
caster = owner.actionsController->getCurrentSpellcaster();
|
||||
|
||||
if(owner.actionsController->spellcastingModeActive())//hero casts spell
|
||||
{
|
||||
spell = owner.actionsController->selectedSpell().toSpell();
|
||||
caster = owner.getActiveHero();
|
||||
}
|
||||
else if(owner.stacksController->activeStackSpellToCast() != SpellID::NONE)//stack casts spell
|
||||
{
|
||||
spell = SpellID(owner.stacksController->activeStackSpellToCast()).toSpell();
|
||||
caster = owner.stacksController->getActiveStack();
|
||||
mode = spells::Mode::CREATURE_ACTIVE;
|
||||
}
|
||||
|
||||
if(caster && spell) //when casting spell
|
||||
if(caster && spell && owner.actionsController->currentActionSpellcasting(hoveredHex) ) //when casting spell
|
||||
{
|
||||
spells::Target target;
|
||||
target.emplace_back(hoveredHex);
|
||||
@ -938,3 +902,14 @@ std::vector<const CStack *> BattleStacksController::selectHoveredStacks()
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::vector<uint32_t> BattleStacksController::getHoveredStacksUnitIds() const
|
||||
{
|
||||
auto result = std::vector<uint32_t>();
|
||||
for (auto const * stack : mouseHoveredStacks)
|
||||
{
|
||||
result.push_back(stack->unitId());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class BattleStacksController
|
||||
/// currently active stack; nullptr - no one
|
||||
const CStack *activeStack;
|
||||
|
||||
/// stacks below mouse pointer (multiple stacks possible while spellcasting), used for border animation
|
||||
/// stacks or their battle queue images below mouse pointer (multiple stacks possible while spellcasting), used for border animation
|
||||
std::vector<const CStack *> mouseHoveredStacks;
|
||||
|
||||
///when animation is playing, we should wait till the end to make the next stack active; nullptr of none
|
||||
@ -79,10 +79,6 @@ class BattleStacksController
|
||||
/// stack that was selected for multi-target spells - Teleport / Sacrifice
|
||||
const CStack *selectedStack;
|
||||
|
||||
/// if true, active stack could possibly cast some target spell
|
||||
bool stackCanCastSpell;
|
||||
si32 creatureSpellToCast;
|
||||
|
||||
/// for giving IDs for animations
|
||||
ui32 animIDhelper;
|
||||
|
||||
@ -123,9 +119,6 @@ public:
|
||||
void startAction(const BattleAction* action);
|
||||
void endAction(const BattleAction* action);
|
||||
|
||||
bool activeStackSpellcaster();
|
||||
SpellID activeStackSpellToCast();
|
||||
|
||||
void activateStack(); //sets activeStack to stackToActivate etc. //FIXME: No, it's not clear at all
|
||||
|
||||
void setActiveStack(const CStack *stack);
|
||||
@ -144,6 +137,7 @@ public:
|
||||
|
||||
const CStack* getActiveStack() const;
|
||||
const CStack* getSelectedStack() const;
|
||||
const std::vector<uint32_t> getHoveredStacksUnitIds() const;
|
||||
|
||||
void update();
|
||||
|
||||
|
@ -37,9 +37,6 @@
|
||||
#include "../../lib/filesystem/ResourceID.h"
|
||||
#include "windows/BattleOptionsWindow.h"
|
||||
|
||||
#include <SDL_surface.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
BattleWindow::BattleWindow(BattleInterface & owner):
|
||||
owner(owner)
|
||||
{
|
||||
@ -80,9 +77,9 @@ BattleWindow::BattleWindow(BattleInterface & owner):
|
||||
std::string queueSize = settings["battle"]["queueSize"].String();
|
||||
|
||||
if(queueSize == "auto")
|
||||
embedQueue = screen->h < 700;
|
||||
embedQueue = GH.screenDimensions().y < 700;
|
||||
else
|
||||
embedQueue = screen->h < 700 || queueSize == "small";
|
||||
embedQueue = GH.screenDimensions().y < 700 || queueSize == "small";
|
||||
|
||||
queue = std::make_shared<StackQueue>(embedQueue, owner);
|
||||
if(!embedQueue && settings["battle"]["showQueue"].Bool())
|
||||
@ -166,9 +163,9 @@ void BattleWindow::deactivate()
|
||||
LOCPLINT->cingconsole->deactivate();
|
||||
}
|
||||
|
||||
void BattleWindow::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void BattleWindow::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
if(key.keysym.sym == SDLK_q && key.state == SDL_PRESSED)
|
||||
if(key == SDLK_q)
|
||||
{
|
||||
if(settings["battle"]["showQueue"].Bool()) //hide queue
|
||||
hideQueue();
|
||||
@ -176,11 +173,11 @@ void BattleWindow::keyPressed(const SDL_KeyboardEvent & key)
|
||||
showQueue();
|
||||
|
||||
}
|
||||
else if(key.keysym.sym == SDLK_f && key.state == SDL_PRESSED)
|
||||
else if(key == SDLK_f)
|
||||
{
|
||||
owner.actionsController->enterCreatureCastingMode();
|
||||
}
|
||||
else if(key.keysym.sym == SDLK_ESCAPE)
|
||||
else if(key == SDLK_ESCAPE)
|
||||
{
|
||||
if(owner.getAnimationCondition(EAnimationEvents::OPENING) == true)
|
||||
CCS->soundh->stopSound(owner.battleIntroSoundChannel);
|
||||
@ -346,6 +343,7 @@ void BattleWindow::showAlternativeActionIcon(PossiblePlayerBattleAction action)
|
||||
|
||||
auto anim = std::make_shared<CAnimation>(iconName);
|
||||
w->setImage(anim, false);
|
||||
w->redraw();
|
||||
}
|
||||
|
||||
void BattleWindow::setAlternativeActions(const std::list<PossiblePlayerBattleAction> & actions)
|
||||
@ -392,7 +390,7 @@ void BattleWindow::bSpellf()
|
||||
if (owner.actionsController->spellcastingModeActive())
|
||||
return;
|
||||
|
||||
if (!owner.myTurn)
|
||||
if (!owner.makingTurn())
|
||||
return;
|
||||
|
||||
auto myHero = owner.currentHero();
|
||||
@ -554,11 +552,16 @@ void BattleWindow::blockUI(bool on)
|
||||
}
|
||||
}
|
||||
|
||||
boost::optional<uint32_t> BattleWindow::getQueueHoveredUnitId()
|
||||
{
|
||||
return queue->getHoveredUnitIdIfAny();
|
||||
}
|
||||
|
||||
void BattleWindow::showAll(SDL_Surface *to)
|
||||
{
|
||||
CIntObject::showAll(to);
|
||||
|
||||
if (screen->w != 800 || screen->h !=600)
|
||||
if (GH.screenDimensions().x != 800 || GH.screenDimensions().y !=600)
|
||||
CMessage::drawBorder(owner.curInt->playerID, to, pos.w+28, pos.h+29, pos.x-14, pos.y-15);
|
||||
}
|
||||
|
||||
|
@ -74,9 +74,12 @@ public:
|
||||
/// Refresh queue after turn order changes
|
||||
void updateQueue();
|
||||
|
||||
/// Get mouse-hovered battle queue unit ID if any found
|
||||
boost::optional<uint32_t> getQueueHoveredUnitId();
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
void show(SDL_Surface *to) override;
|
||||
void showAll(SDL_Surface *to) override;
|
||||
|
@ -78,10 +78,7 @@ float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, c
|
||||
return baseSpeed;
|
||||
|
||||
case ECreatureAnimType::HOLDING:
|
||||
if ( creature->animation.idleAnimationTime > 0.01)
|
||||
return speed / creature->animation.idleAnimationTime;
|
||||
else
|
||||
return 0.f; // this animation is disabled for current creature
|
||||
return creature->animation.idleAnimationTime;
|
||||
|
||||
case ECreatureAnimType::SHOOT_UP:
|
||||
case ECreatureAnimType::SHOOT_FRONT:
|
||||
@ -315,7 +312,7 @@ void CreatureAnimation::playOnce( ECreatureAnimType type )
|
||||
|
||||
inline int getBorderStrength(float time)
|
||||
{
|
||||
float borderStrength = fabs(vstd::round(time) - time) * 2; // generate value in range 0-1
|
||||
float borderStrength = fabs(std::round(time) - time) * 2; // generate value in range 0-1
|
||||
|
||||
return static_cast<int>(borderStrength * 155 + 100); // scale to 0-255
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "CursorHandler.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../CMT.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
@ -27,6 +28,14 @@
|
||||
#include <SDL_timer.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
#ifdef VCMI_IOS
|
||||
#include "ios/utils.h"
|
||||
#endif
|
||||
|
||||
extern std::queue<SDL_Event> SDLEventsQueue;
|
||||
extern boost::mutex eventsM;
|
||||
|
||||
@ -118,7 +127,7 @@ void CGuiHandler::popInt(std::shared_ptr<IShowActivatable> top)
|
||||
listInt.front()->activate();
|
||||
totalRedraw();
|
||||
|
||||
pushSDLEvent(SDL_USEREVENT, EUserEvent::INTERFACE_CHANGED);
|
||||
pushUserEvent(EUserEvent::INTERFACE_CHANGED);
|
||||
}
|
||||
|
||||
void CGuiHandler::pushInt(std::shared_ptr<IShowActivatable> newInt)
|
||||
@ -137,7 +146,7 @@ void CGuiHandler::pushInt(std::shared_ptr<IShowActivatable> newInt)
|
||||
objsToBlit.push_back(newInt);
|
||||
totalRedraw();
|
||||
|
||||
pushSDLEvent(SDL_USEREVENT, EUserEvent::INTERFACE_CHANGED);
|
||||
pushUserEvent(EUserEvent::INTERFACE_CHANGED);
|
||||
}
|
||||
|
||||
void CGuiHandler::popInts(int howMany)
|
||||
@ -160,7 +169,7 @@ void CGuiHandler::popInts(int howMany)
|
||||
}
|
||||
fakeMouseMove();
|
||||
|
||||
pushSDLEvent(SDL_USEREVENT, EUserEvent::INTERFACE_CHANGED);
|
||||
pushUserEvent(EUserEvent::INTERFACE_CHANGED);
|
||||
}
|
||||
|
||||
std::shared_ptr<IShowActivatable> CGuiHandler::topInt()
|
||||
@ -203,7 +212,12 @@ void CGuiHandler::handleEvents()
|
||||
{
|
||||
continueEventHandling = true;
|
||||
SDL_Event currentEvent = SDLEventsQueue.front();
|
||||
cursorPosition = Point(currentEvent.motion.x, currentEvent.motion.y);
|
||||
|
||||
if (currentEvent.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
cursorPosition = Point(currentEvent.motion.x, currentEvent.motion.y);
|
||||
mouseButtonsMask = currentEvent.motion.state;
|
||||
}
|
||||
SDLEventsQueue.pop();
|
||||
|
||||
// In a sequence of mouse motion events, skip all but the last one.
|
||||
@ -257,6 +271,59 @@ void CGuiHandler::fakeMouseMove()
|
||||
fakeMoveCursor(0, 0);
|
||||
}
|
||||
|
||||
void CGuiHandler::startTextInput(const Rect & whereInput)
|
||||
{
|
||||
#ifdef VCMI_APPLE
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
#endif
|
||||
|
||||
// TODO ios: looks like SDL bug actually, try fixing there
|
||||
auto renderer = SDL_GetRenderer(mainWindow);
|
||||
float scaleX, scaleY;
|
||||
SDL_Rect viewport;
|
||||
SDL_RenderGetScale(renderer, &scaleX, &scaleY);
|
||||
SDL_RenderGetViewport(renderer, &viewport);
|
||||
|
||||
#ifdef VCMI_IOS
|
||||
const auto nativeScale = iOS_utils::screenScale();
|
||||
scaleX /= nativeScale;
|
||||
scaleY /= nativeScale;
|
||||
#endif
|
||||
|
||||
SDL_Rect rectInScreenCoordinates;
|
||||
rectInScreenCoordinates.x = (viewport.x + whereInput.x) * scaleX;
|
||||
rectInScreenCoordinates.y = (viewport.y + whereInput.y) * scaleY;
|
||||
rectInScreenCoordinates.w = whereInput.w * scaleX;
|
||||
rectInScreenCoordinates.h = whereInput.h * scaleY;
|
||||
|
||||
SDL_SetTextInputRect(&rectInScreenCoordinates);
|
||||
|
||||
if (SDL_IsTextInputActive() == SDL_FALSE)
|
||||
{
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuiHandler::stopTextInput()
|
||||
{
|
||||
#ifdef VCMI_APPLE
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
#endif
|
||||
|
||||
if (SDL_IsTextInputActive() == SDL_TRUE)
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGuiHandler::fakeMouseButtonEventRelativeMode(bool down, bool right)
|
||||
{
|
||||
SDL_Event event;
|
||||
@ -280,9 +347,9 @@ void CGuiHandler::fakeMouseButtonEventRelativeMode(bool down, bool right)
|
||||
SDL_RenderGetScale(mainRenderer, &xScale, &yScale);
|
||||
|
||||
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
|
||||
CSDL_Ext::warpMouse(
|
||||
moveCursorToPosition( Point(
|
||||
(int)(sme.x * xScale) + (w - rLogicalWidth * xScale) / 2,
|
||||
(int)(sme.y * yScale + (h - rLogicalHeight * yScale) / 2));
|
||||
(int)(sme.y * yScale + (h - rLogicalHeight * yScale) / 2)));
|
||||
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
|
||||
|
||||
event.button = sme;
|
||||
@ -345,7 +412,7 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
bool keysCaptured = false;
|
||||
for(auto i = keyinterested.begin(); i != keyinterested.end() && continueEventHandling; i++)
|
||||
{
|
||||
if((*i)->captureThisEvent(key))
|
||||
if((*i)->captureThisKey(key.keysym.sym))
|
||||
{
|
||||
keysCaptured = true;
|
||||
break;
|
||||
@ -354,8 +421,13 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
|
||||
std::list<CIntObject*> miCopy = keyinterested;
|
||||
for(auto i = miCopy.begin(); i != miCopy.end() && continueEventHandling; i++)
|
||||
if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisEvent(key)))
|
||||
(**i).keyPressed(key);
|
||||
if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisKey(key.keysym.sym)))
|
||||
{
|
||||
if (key.state == SDL_PRESSED)
|
||||
(**i).keyPressed(key.keysym.sym);
|
||||
if (key.state == SDL_RELEASED)
|
||||
(**i).keyReleased(key.keysym.sym);
|
||||
}
|
||||
}
|
||||
else if(current.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
@ -387,14 +459,14 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
lastClickTime = SDL_GetTicks();
|
||||
|
||||
if(!doubleClicked)
|
||||
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, true);
|
||||
handleMouseButtonClick(lclickable, MouseButton::LEFT, true);
|
||||
break;
|
||||
}
|
||||
case SDL_BUTTON_RIGHT:
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, true);
|
||||
handleMouseButtonClick(rclickable, MouseButton::RIGHT, true);
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
handleMouseButtonClick(mclickable, EIntObjMouseBtnType::MIDDLE, true);
|
||||
handleMouseButtonClick(mclickable, MouseButton::MIDDLE, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -416,14 +488,14 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
{
|
||||
for(auto it : textInterested)
|
||||
{
|
||||
it->textInputed(current.text);
|
||||
it->textInputed(current.text.text);
|
||||
}
|
||||
}
|
||||
else if(current.type == SDL_TEXTEDITING)
|
||||
{
|
||||
for(auto it : textInterested)
|
||||
{
|
||||
it->textEdited(current.edit);
|
||||
it->textEdited(current.edit.text);
|
||||
}
|
||||
}
|
||||
else if(current.type == SDL_MOUSEBUTTONUP)
|
||||
@ -433,13 +505,13 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
switch(current.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, false);
|
||||
handleMouseButtonClick(lclickable, MouseButton::LEFT, false);
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
||||
handleMouseButtonClick(rclickable, MouseButton::RIGHT, false);
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
handleMouseButtonClick(mclickable, EIntObjMouseBtnType::MIDDLE, false);
|
||||
handleMouseButtonClick(mclickable, MouseButton::MIDDLE, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -471,7 +543,7 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
{
|
||||
convertTouchToMouse(¤t);
|
||||
handleMouseMotion(current);
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, true);
|
||||
handleMouseButtonClick(rclickable, MouseButton::RIGHT, true);
|
||||
}
|
||||
#endif //VCMI_IOS
|
||||
}
|
||||
@ -495,14 +567,14 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
{
|
||||
convertTouchToMouse(¤t);
|
||||
handleMouseMotion(current);
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
||||
handleMouseButtonClick(rclickable, MouseButton::RIGHT, false);
|
||||
multifinger = fingerCount != 0;
|
||||
}
|
||||
#endif //VCMI_IOS
|
||||
}
|
||||
} //event end
|
||||
|
||||
void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed)
|
||||
void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed)
|
||||
{
|
||||
auto hlp = interestedObjs;
|
||||
for(auto i = hlp.begin(); i != hlp.end() && continueEventHandling; i++)
|
||||
@ -546,7 +618,9 @@ void CGuiHandler::handleMouseMotion(const SDL_Event & current)
|
||||
elem->hovered = true;
|
||||
}
|
||||
|
||||
handleMoveInterested(current.motion);
|
||||
// do not send motion events for events outside our window
|
||||
//if (current.motion.windowID == 0)
|
||||
handleMoveInterested(current.motion);
|
||||
}
|
||||
|
||||
void CGuiHandler::simpleRedraw()
|
||||
@ -566,7 +640,7 @@ void CGuiHandler::handleMoveInterested(const SDL_MouseMotionEvent & motion)
|
||||
{
|
||||
if(elem->strongInterest || Rect::createAround(elem->pos, 1).isInside( motion.x, motion.y)) //checking bounds including border fixes bug #2476
|
||||
{
|
||||
(elem)->mouseMoved(motion);
|
||||
(elem)->mouseMoved(Point(motion.x, motion.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -612,13 +686,16 @@ void CGuiHandler::renderFrame()
|
||||
|
||||
|
||||
CGuiHandler::CGuiHandler()
|
||||
: lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false),
|
||||
multifinger(false)
|
||||
: lastClick(-500, -500)
|
||||
, lastClickTime(0)
|
||||
, defActionsDef(0)
|
||||
, captureChildren(false)
|
||||
, multifinger(false)
|
||||
, mouseButtonsMask(0)
|
||||
, continueEventHandling(true)
|
||||
, curInt(nullptr)
|
||||
, statusbar(nullptr)
|
||||
{
|
||||
continueEventHandling = true;
|
||||
curInt = nullptr;
|
||||
statusbar = nullptr;
|
||||
|
||||
// Creates the FPS manager and sets the framerate to 48 which is doubled the value of the original Heroes 3 FPS rate
|
||||
mainFPSmng = new CFramerateManager(60);
|
||||
//do not init CFramerateManager here --AVS
|
||||
@ -632,6 +709,27 @@ CGuiHandler::~CGuiHandler()
|
||||
delete terminate_cond;
|
||||
}
|
||||
|
||||
|
||||
void CGuiHandler::moveCursorToPosition(const Point & position)
|
||||
{
|
||||
SDL_WarpMouseInWindow(mainWindow, position.x, position.y);
|
||||
}
|
||||
|
||||
bool CGuiHandler::isKeyboardCtrlDown() const
|
||||
{
|
||||
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LCTRL] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RCTRL];
|
||||
}
|
||||
|
||||
bool CGuiHandler::isKeyboardAltDown() const
|
||||
{
|
||||
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LALT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RALT];
|
||||
}
|
||||
|
||||
bool CGuiHandler::isKeyboardShiftDown() const
|
||||
{
|
||||
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LSHIFT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RSHIFT];
|
||||
}
|
||||
|
||||
void CGuiHandler::breakEventHandling()
|
||||
{
|
||||
continueEventHandling = false;
|
||||
@ -642,6 +740,28 @@ const Point & CGuiHandler::getCursorPosition() const
|
||||
return cursorPosition;
|
||||
}
|
||||
|
||||
Point CGuiHandler::screenDimensions() const
|
||||
{
|
||||
return Point(screen->w, screen->h);
|
||||
}
|
||||
|
||||
bool CGuiHandler::isMouseButtonPressed() const
|
||||
{
|
||||
return mouseButtonsMask > 0;
|
||||
}
|
||||
|
||||
bool CGuiHandler::isMouseButtonPressed(MouseButton button) const
|
||||
{
|
||||
static_assert(static_cast<uint32_t>(MouseButton::LEFT) == SDL_BUTTON_LEFT, "mismatch between VCMI and SDL enum!");
|
||||
static_assert(static_cast<uint32_t>(MouseButton::MIDDLE) == SDL_BUTTON_MIDDLE, "mismatch between VCMI and SDL enum!");
|
||||
static_assert(static_cast<uint32_t>(MouseButton::RIGHT) == SDL_BUTTON_RIGHT, "mismatch between VCMI and SDL enum!");
|
||||
static_assert(static_cast<uint32_t>(MouseButton::EXTRA1) == SDL_BUTTON_X1, "mismatch between VCMI and SDL enum!");
|
||||
static_assert(static_cast<uint32_t>(MouseButton::EXTRA2) == SDL_BUTTON_X2, "mismatch between VCMI and SDL enum!");
|
||||
|
||||
uint32_t index = static_cast<uint32_t>(button);
|
||||
return mouseButtonsMask & SDL_BUTTON(index);
|
||||
}
|
||||
|
||||
void CGuiHandler::drawFPSCounter()
|
||||
{
|
||||
static SDL_Rect overlay = { 0, 0, 64, 32};
|
||||
@ -719,11 +839,17 @@ bool CGuiHandler::amIGuiThread()
|
||||
return inGuiThread.get() && *inGuiThread;
|
||||
}
|
||||
|
||||
void CGuiHandler::pushSDLEvent(int type, int usercode)
|
||||
void CGuiHandler::pushUserEvent(EUserEvent usercode)
|
||||
{
|
||||
pushUserEvent(usercode, nullptr);
|
||||
}
|
||||
|
||||
void CGuiHandler::pushUserEvent(EUserEvent usercode, void * userdata)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type = type;
|
||||
event.user.code = usercode; // not necessarily used
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = static_cast<int32_t>(usercode);
|
||||
event.user.data1 = userdata;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
|
@ -9,12 +9,15 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "MouseButton.h"
|
||||
#include "../../lib/Point.h"
|
||||
#include "SDL_keycode.h"
|
||||
|
||||
#include <SDL_keycode.h>
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
template <typename T> struct CondSh;
|
||||
class Rect;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
@ -27,10 +30,9 @@ class CIntObject;
|
||||
class IUpdateable;
|
||||
class IShowActivatable;
|
||||
class IShowable;
|
||||
enum class EIntObjMouseBtnType;
|
||||
|
||||
// TODO: event handling need refactoring
|
||||
enum EUserEvent
|
||||
enum class EUserEvent
|
||||
{
|
||||
/*CHANGE_SCREEN_RESOLUTION = 1,*/
|
||||
RETURN_TO_MAIN_MENU = 2,
|
||||
@ -71,6 +73,7 @@ public:
|
||||
|
||||
private:
|
||||
Point cursorPosition;
|
||||
uint32_t mouseButtonsMask;
|
||||
|
||||
std::vector<std::shared_ptr<IShowActivatable>> disposed;
|
||||
|
||||
@ -90,7 +93,7 @@ private:
|
||||
CIntObjectList textInterested;
|
||||
|
||||
|
||||
void handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed);
|
||||
void handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed);
|
||||
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
||||
void handleCurrentEvent(SDL_Event ¤t);
|
||||
void handleMouseMotion(const SDL_Event & current);
|
||||
@ -107,8 +110,28 @@ public:
|
||||
//objs to blit
|
||||
std::vector<std::shared_ptr<IShowActivatable>> objsToBlit;
|
||||
|
||||
/// returns current position of mouse cursor, relative to vcmi window
|
||||
const Point & getCursorPosition() const;
|
||||
|
||||
Point screenDimensions() const;
|
||||
|
||||
/// returns true if at least one mouse button is pressed
|
||||
bool isMouseButtonPressed() const;
|
||||
|
||||
/// returns true if specified mouse button is pressed
|
||||
bool isMouseButtonPressed(MouseButton button) const;
|
||||
|
||||
/// returns true if chosen keyboard key is currently pressed down
|
||||
bool isKeyboardAltDown() const;
|
||||
bool isKeyboardCtrlDown() const;
|
||||
bool isKeyboardShiftDown() const;
|
||||
|
||||
void startTextInput(const Rect & where);
|
||||
void stopTextInput();
|
||||
|
||||
/// moves mouse pointer into specified position inside vcmi window
|
||||
void moveCursorToPosition(const Point & position);
|
||||
|
||||
IUpdateable *curInt;
|
||||
|
||||
Point lastClick;
|
||||
@ -155,7 +178,8 @@ public:
|
||||
static bool isNumKey(SDL_Keycode key, bool number = true); //checks if key is on numpad (numbers - check only for numpad digits)
|
||||
static bool isArrowKey(SDL_Keycode key);
|
||||
static bool amIGuiThread();
|
||||
static void pushSDLEvent(int type, int usercode = 0);
|
||||
static void pushUserEvent(EUserEvent usercode);
|
||||
static void pushUserEvent(EUserEvent usercode, void * userdata);
|
||||
|
||||
CondSh<bool> * terminate_cond; // confirm termination
|
||||
};
|
||||
|
@ -13,10 +13,9 @@
|
||||
#include "CGuiHandler.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../CMT.h"
|
||||
|
||||
#include <SDL_pixels.h>
|
||||
#include <SDL_surface.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
IShowActivatable::IShowActivatable()
|
||||
{
|
||||
@ -146,18 +145,18 @@ void CIntObject::deactivate(ui16 what)
|
||||
GH.handleElementDeActivate(this, what);
|
||||
}
|
||||
|
||||
void CIntObject::click(EIntObjMouseBtnType btn, tribool down, bool previousState)
|
||||
void CIntObject::click(MouseButton btn, tribool down, bool previousState)
|
||||
{
|
||||
switch(btn)
|
||||
{
|
||||
default:
|
||||
case EIntObjMouseBtnType::LEFT:
|
||||
case MouseButton::LEFT:
|
||||
clickLeft(down, previousState);
|
||||
break;
|
||||
case EIntObjMouseBtnType::MIDDLE:
|
||||
case MouseButton::MIDDLE:
|
||||
clickMiddle(down, previousState);
|
||||
break;
|
||||
case EIntObjMouseBtnType::RIGHT:
|
||||
case MouseButton::RIGHT:
|
||||
clickRight(down, previousState);
|
||||
break;
|
||||
}
|
||||
@ -228,8 +227,8 @@ void CIntObject::fitToScreen(int borderWidth, bool propagate)
|
||||
Point newPos = pos.topLeft();
|
||||
vstd::amax(newPos.x, borderWidth);
|
||||
vstd::amax(newPos.y, borderWidth);
|
||||
vstd::amin(newPos.x, screen->w - borderWidth - pos.w);
|
||||
vstd::amin(newPos.y, screen->h - borderWidth - pos.h);
|
||||
vstd::amin(newPos.x, GH.screenDimensions().x - borderWidth - pos.w);
|
||||
vstd::amin(newPos.y, GH.screenDimensions().y - borderWidth - pos.h);
|
||||
if (newPos != pos.topLeft())
|
||||
moveTo(newPos, propagate);
|
||||
}
|
||||
@ -309,7 +308,7 @@ const Rect & CIntObject::center( const Rect &r, bool propagate )
|
||||
{
|
||||
pos.w = r.w;
|
||||
pos.h = r.h;
|
||||
return center(Point(screen->w/2, screen->h/2), propagate);
|
||||
return center(Point(GH.screenDimensions().x/2, GH.screenDimensions().y/2), propagate);
|
||||
}
|
||||
|
||||
const Rect & CIntObject::center( bool propagate )
|
||||
@ -325,7 +324,7 @@ const Rect & CIntObject::center(const Point & p, bool propagate)
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool CIntObject::captureThisEvent(const SDL_KeyboardEvent & key)
|
||||
bool CIntObject::captureThisKey(const SDL_Keycode & key)
|
||||
{
|
||||
return captureAllKeys;
|
||||
}
|
||||
@ -343,14 +342,26 @@ CKeyShortcut::CKeyShortcut(std::set<int> Keys)
|
||||
:assignedKeys(Keys)
|
||||
{}
|
||||
|
||||
void CKeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void CKeyShortcut::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
if(vstd::contains(assignedKeys,key.keysym.sym)
|
||||
|| vstd::contains(assignedKeys, CGuiHandler::numToDigit(key.keysym.sym)))
|
||||
if(vstd::contains(assignedKeys,key)
|
||||
|| vstd::contains(assignedKeys, CGuiHandler::numToDigit(key)))
|
||||
{
|
||||
bool prev = mouseState(EIntObjMouseBtnType::LEFT);
|
||||
updateMouseState(EIntObjMouseBtnType::LEFT, key.state == SDL_PRESSED);
|
||||
clickLeft(key.state == SDL_PRESSED, prev);
|
||||
bool prev = mouseState(MouseButton::LEFT);
|
||||
updateMouseState(MouseButton::LEFT, true);
|
||||
clickLeft(true, prev);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CKeyShortcut::keyReleased(const SDL_Keycode & key)
|
||||
{
|
||||
if(vstd::contains(assignedKeys,key)
|
||||
|| vstd::contains(assignedKeys, CGuiHandler::numToDigit(key)))
|
||||
{
|
||||
bool prev = mouseState(MouseButton::LEFT);
|
||||
updateMouseState(MouseButton::LEFT, false);
|
||||
clickLeft(false, prev);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,17 +9,15 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../lib/Rect.h"
|
||||
#include "MouseButton.h"
|
||||
#include "../render/Graphics.h"
|
||||
#include "../../lib/Rect.h"
|
||||
|
||||
struct SDL_Surface;
|
||||
class CGuiHandler;
|
||||
class CPicture;
|
||||
|
||||
struct SDL_KeyboardEvent;
|
||||
struct SDL_TextInputEvent;
|
||||
struct SDL_TextEditingEvent;
|
||||
struct SDL_MouseMotionEvent;
|
||||
typedef int32_t SDL_Keycode;
|
||||
|
||||
using boost::logic::tribool;
|
||||
|
||||
@ -62,9 +60,6 @@ public:
|
||||
virtual ~IShowActivatable(){};
|
||||
};
|
||||
|
||||
enum class EIntObjMouseBtnType { LEFT, MIDDLE, RIGHT };
|
||||
//typedef ui16 ActivityFlag;
|
||||
|
||||
// Base UI element
|
||||
class CIntObject : public IShowActivatable //interface object
|
||||
{
|
||||
@ -74,7 +69,7 @@ class CIntObject : public IShowActivatable //interface object
|
||||
int toNextTick;
|
||||
int timerDelay;
|
||||
|
||||
std::map<EIntObjMouseBtnType, bool> currentMouseState;
|
||||
std::map<MouseButton, bool> currentMouseState;
|
||||
|
||||
void onTimer(int timePassed);
|
||||
|
||||
@ -108,10 +103,10 @@ public:
|
||||
CIntObject(int used=0, Point offset=Point());
|
||||
virtual ~CIntObject();
|
||||
|
||||
void updateMouseState(EIntObjMouseBtnType btn, bool state) { currentMouseState[btn] = state; }
|
||||
bool mouseState(EIntObjMouseBtnType btn) const { return currentMouseState.count(btn) ? currentMouseState.at(btn) : false; }
|
||||
void updateMouseState(MouseButton btn, bool state) { currentMouseState[btn] = state; }
|
||||
bool mouseState(MouseButton btn) const { return currentMouseState.count(btn) ? currentMouseState.at(btn) : false; }
|
||||
|
||||
virtual void click(EIntObjMouseBtnType btn, tribool down, bool previousState);
|
||||
virtual void click(MouseButton btn, tribool down, bool previousState);
|
||||
virtual void clickLeft(tribool down, bool previousState) {}
|
||||
virtual void clickRight(tribool down, bool previousState) {}
|
||||
virtual void clickMiddle(tribool down, bool previousState) {}
|
||||
@ -122,15 +117,16 @@ public:
|
||||
|
||||
//keyboard handling
|
||||
bool captureAllKeys; //if true, only this object should get info about pressed keys
|
||||
virtual void keyPressed(const SDL_KeyboardEvent & key){}
|
||||
virtual bool captureThisEvent(const SDL_KeyboardEvent & key); //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
|
||||
virtual void keyPressed(const SDL_Keycode & key){}
|
||||
virtual void keyReleased(const SDL_Keycode & key){}
|
||||
virtual bool captureThisKey(const SDL_Keycode & key); //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
|
||||
|
||||
virtual void textInputed(const SDL_TextInputEvent & event){};
|
||||
virtual void textEdited(const SDL_TextEditingEvent & event){};
|
||||
virtual void textInputed(const std::string & enteredText){};
|
||||
virtual void textEdited(const std::string & enteredText){};
|
||||
|
||||
//mouse movement handling
|
||||
bool strongInterest; //if true - report all mouse movements, if not - only when hovered
|
||||
virtual void mouseMoved (const SDL_MouseMotionEvent & sEvent){}
|
||||
virtual void mouseMoved (const Point & cursorPosition){}
|
||||
|
||||
//time handling
|
||||
void setTimer(int msToTrigger);//set timer delay and activate timer if needed.
|
||||
@ -205,7 +201,9 @@ public:
|
||||
CKeyShortcut();
|
||||
CKeyShortcut(int key);
|
||||
CKeyShortcut(std::set<int> Keys);
|
||||
virtual void keyPressed(const SDL_KeyboardEvent & key) override; //call-in
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void keyReleased(const SDL_Keycode & key) override;
|
||||
|
||||
};
|
||||
|
||||
class WindowBase : public CIntObject
|
||||
|
@ -17,17 +17,9 @@
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../CMT.h"
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
std::unique_ptr<ICursor> CursorHandler::createCursor()
|
||||
{
|
||||
if (settings["video"]["cursor"].String() == "auto")
|
||||
@ -254,18 +246,6 @@ std::shared_ptr<IImage> CursorHandler::getCurrentImage()
|
||||
return cursors[static_cast<size_t>(type)]->getImage(frame);
|
||||
}
|
||||
|
||||
void CursorHandler::centerCursor()
|
||||
{
|
||||
Point screenSize {screen->w, screen->h};
|
||||
pos = screenSize / 2 - getPivotOffset();
|
||||
|
||||
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
|
||||
CSDL_Ext::warpMouse(pos.x, pos.y);
|
||||
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
|
||||
|
||||
cursor->setCursorPosition(pos);
|
||||
}
|
||||
|
||||
void CursorHandler::updateSpellcastCursor()
|
||||
{
|
||||
static const float frameDisplayDuration = 0.1f; // H3 uses 100 ms per frame
|
||||
|
@ -178,7 +178,4 @@ public:
|
||||
|
||||
/// change cursor's positions to (x, y)
|
||||
void cursorMove(const int & x, const int & y);
|
||||
/// Move cursor to screen center
|
||||
void centerCursor();
|
||||
|
||||
};
|
||||
|
@ -1,23 +1,19 @@
|
||||
/*
|
||||
* Ability.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
namespace abilities
|
||||
{
|
||||
|
||||
class DLL_LINKAGE Ability
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
/*
|
||||
* MouseButton.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
enum class MouseButton
|
||||
{
|
||||
LEFT = 1,
|
||||
MIDDLE = 2,
|
||||
RIGHT = 3,
|
||||
EXTRA1 = 4,
|
||||
EXTRA2 = 5
|
||||
};
|
@ -454,7 +454,7 @@ void CBonusSelection::restartMap()
|
||||
close();
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [=]()
|
||||
{
|
||||
LOCPLINT->sendCustomEvent(EUserEvent::RESTART_GAME);
|
||||
GH.pushUserEvent(EUserEvent::RESTART_GAME);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,6 @@
|
||||
#include "../../lib/mapping/CMapInfo.h"
|
||||
#include "../../lib/serializer/Connection.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
ISelectionScreenInfo::ISelectionScreenInfo(ESelectionScreen ScreenType)
|
||||
: screenType(ScreenType)
|
||||
{
|
||||
@ -320,9 +318,9 @@ CChatBox::CChatBox(const Rect & rect)
|
||||
chatHistory->label->color = Colors::GREEN;
|
||||
}
|
||||
|
||||
void CChatBox::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void CChatBox::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
if(key.keysym.sym == SDLK_RETURN && key.state == SDL_PRESSED && inputBox->getText().size())
|
||||
if(key == SDLK_RETURN && inputBox->getText().size())
|
||||
{
|
||||
CSH->sendMessage(inputBox->getText());
|
||||
inputBox->setText("");
|
||||
|
@ -120,8 +120,7 @@ public:
|
||||
|
||||
CChatBox(const Rect & rect);
|
||||
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void addNewMessage(const std::string & text);
|
||||
};
|
||||
|
||||
|
@ -35,8 +35,6 @@
|
||||
#include "../../lib/mapping/CMapInfo.h"
|
||||
#include "../../lib/serializer/Connection.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
bool mapSorter::operator()(const std::shared_ptr<CMapInfo> aaa, const std::shared_ptr<CMapInfo> bbb)
|
||||
{
|
||||
auto a = aaa->mapHeader.get();
|
||||
@ -280,13 +278,10 @@ void SelectionTab::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionTab::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void SelectionTab::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
if(key.state != SDL_PRESSED)
|
||||
return;
|
||||
|
||||
int moveBy = 0;
|
||||
switch(key.keysym.sym)
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_UP:
|
||||
moveBy = -1;
|
||||
|
@ -66,7 +66,8 @@ public:
|
||||
void toggleMode();
|
||||
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
|
||||
void onDoubleClick() override;
|
||||
|
||||
void filter(int size, bool selectFirst = false); //0 - all
|
||||
|
@ -16,25 +16,8 @@
|
||||
#include "../lobby/CBonusSelection.h"
|
||||
#include "../lobby/CSelectionBase.h"
|
||||
#include "../lobby/CLobbyScreen.h"
|
||||
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
#include "../../lib/filesystem/CCompressedStream.h"
|
||||
|
||||
#include "../gui/CursorHandler.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/JsonNode.h"
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../CVideoHandler.h"
|
||||
#include "../../lib/serializer/Connection.h"
|
||||
#include "../../lib/serializer/CTypeList.h"
|
||||
#include "../../lib/VCMIDirs.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
#include "../windows/GUIClasses.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../../CCallback.h"
|
||||
#include "../Client.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
@ -43,6 +26,24 @@
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../CServerHandler.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../CVideoHandler.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../Client.h"
|
||||
#include "../CMT.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/JsonNode.h"
|
||||
#include "../../lib/serializer/Connection.h"
|
||||
#include "../../lib/serializer/CTypeList.h"
|
||||
#include "../../lib/filesystem/Filesystem.h"
|
||||
#include "../../lib/filesystem/CCompressedStream.h"
|
||||
#include "../../lib/VCMIDirs.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
#include "../../lib/CStopWatch.h"
|
||||
#include "../../lib/NetPacksLobby.h"
|
||||
#include "../../lib/CThreadHelper.h"
|
||||
@ -52,7 +53,6 @@
|
||||
#include "../../lib/CondSh.h"
|
||||
#include "../../lib/mapping/CCampaignHandler.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
@ -61,9 +61,7 @@ ISelectionScreenInfo * SEL;
|
||||
|
||||
static void do_quit()
|
||||
{
|
||||
SDL_Event event;
|
||||
event.quit.type = SDL_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
GH.pushUserEvent(EUserEvent::FORCE_QUIT);
|
||||
}
|
||||
|
||||
CMenuScreen::CMenuScreen(const JsonNode & configNode)
|
||||
@ -73,7 +71,7 @@ CMenuScreen::CMenuScreen(const JsonNode & configNode)
|
||||
|
||||
background = std::make_shared<CPicture>(config["background"].String());
|
||||
if(config["scalable"].Bool())
|
||||
background->scaleTo(Point(screen->w, screen->h));
|
||||
background->scaleTo(GH.screenDimensions());
|
||||
|
||||
pos = background->center();
|
||||
|
||||
@ -276,8 +274,8 @@ const JsonNode & CMainMenuConfig::getCampaigns() const
|
||||
|
||||
CMainMenu::CMainMenu()
|
||||
{
|
||||
pos.w = screen->w;
|
||||
pos.h = screen->h;
|
||||
pos.w = GH.screenDimensions().x;
|
||||
pos.h = GH.screenDimensions().y;
|
||||
|
||||
GH.defActionsDef = 63;
|
||||
menu = std::make_shared<CMenuScreen>(CMainMenuConfig::get().getConfig()["window"]);
|
||||
@ -484,7 +482,7 @@ void CSimpleJoinScreen::connectToServer()
|
||||
{
|
||||
textTitle->setText("Connecting...");
|
||||
buttonOk->block(true);
|
||||
CSDL_Ext::stopTextInput();
|
||||
GH.stopTextInput();
|
||||
|
||||
boost::thread(&CSimpleJoinScreen::connectThread, this, inputAddress->getText(), boost::lexical_cast<ui16>(inputPort->getText()));
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../CVideoHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../lib/mapping/CCampaignHandler.h"
|
||||
|
||||
|
@ -81,7 +81,7 @@ SDL_Surface * BitmapHandler::loadH3PCX(ui8 * pcx, size_t size)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
#ifdef VCMI_ENDIAN_BIG
|
||||
int bmask = 0xff0000;
|
||||
int gmask = 0x00ff00;
|
||||
int rmask = 0x0000ff;
|
||||
|
26
client/render/Colors.cpp
Normal file
26
client/render/Colors.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* IFont.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "Colors.h"
|
||||
|
||||
#include <SDL_pixels.h>
|
||||
|
||||
const SDL_Color Colors::YELLOW = { 229, 215, 123, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::WHITE = { 255, 243, 222, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::METALLIC_GOLD = { 173, 142, 66, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::GREEN = { 0, 255, 0, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::ORANGE = { 232, 184, 32, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::BRIGHT_YELLOW = { 242, 226, 110, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::DEFAULT_KEY_COLOR = {0, 255, 255, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::RED = {255, 0, 0, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::PURPLE = {255, 75, 125, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::BLACK = {0, 0, 0, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::TRANSPARENCY = {0, 0, 0, SDL_ALPHA_TRANSPARENT};
|
50
client/render/Colors.h
Normal file
50
client/render/Colors.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* ICursor.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
struct SDL_Color;
|
||||
|
||||
/**
|
||||
* The colors class defines color constants of type SDL_Color.
|
||||
*/
|
||||
class Colors
|
||||
{
|
||||
public:
|
||||
/** the h3 yellow color, typically used for headlines */
|
||||
static const SDL_Color YELLOW;
|
||||
|
||||
/** the standard h3 white color */
|
||||
static const SDL_Color WHITE;
|
||||
|
||||
/** the metallic gold color used mostly as a border around buttons */
|
||||
static const SDL_Color METALLIC_GOLD;
|
||||
|
||||
/** green color used for in-game console */
|
||||
static const SDL_Color GREEN;
|
||||
|
||||
/** the h3 orange color, used for blocked buttons */
|
||||
static const SDL_Color ORANGE;
|
||||
|
||||
/** the h3 bright yellow color, used for selection border */
|
||||
static const SDL_Color BRIGHT_YELLOW;
|
||||
|
||||
/** default key color for all 8 & 24 bit graphics */
|
||||
static const SDL_Color DEFAULT_KEY_COLOR;
|
||||
|
||||
/// Selected creature card
|
||||
static const SDL_Color RED;
|
||||
|
||||
/// Minimap border
|
||||
static const SDL_Color PURPLE;
|
||||
|
||||
static const SDL_Color BLACK;
|
||||
|
||||
static const SDL_Color TRANSPARENCY;
|
||||
};
|
@ -42,8 +42,6 @@
|
||||
|
||||
#include <SDL_surface.h>
|
||||
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
Graphics * graphics = nullptr;
|
||||
|
||||
void Graphics::loadPaletteAndColors()
|
||||
|
@ -10,7 +10,8 @@
|
||||
#include "StdInc.h"
|
||||
#include "CTrueTypeFont.h"
|
||||
|
||||
#include "SDL_Extensions.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../lib/JsonNode.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
|
@ -11,8 +11,9 @@
|
||||
#include "StdInc.h"
|
||||
#include "CursorHardware.h"
|
||||
|
||||
#include "SDL_Extensions.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "SDL_Extensions.h"
|
||||
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_events.h>
|
||||
|
@ -11,9 +11,10 @@
|
||||
#include "StdInc.h"
|
||||
#include "CursorSoftware.h"
|
||||
|
||||
#include "SDL_Extensions.h"
|
||||
|
||||
#include "../render/Colors.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../CMT.h"
|
||||
#include "SDL_Extensions.h"
|
||||
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_events.h>
|
||||
|
@ -13,40 +13,10 @@
|
||||
#include "SDL_PixelAccess.h"
|
||||
|
||||
#include "../render/Graphics.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../CMT.h"
|
||||
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_video.h>
|
||||
#include <SDL_events.h>
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
#ifdef VCMI_IOS
|
||||
#include "ios/utils.h"
|
||||
#endif
|
||||
|
||||
const SDL_Color Colors::YELLOW = { 229, 215, 123, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::WHITE = { 255, 243, 222, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::METALLIC_GOLD = { 173, 142, 66, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::GREEN = { 0, 255, 0, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::ORANGE = { 232, 184, 32, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::BRIGHT_YELLOW = { 242, 226, 110, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color Colors::DEFAULT_KEY_COLOR = {0, 255, 255, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::RED = {255, 0, 0, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::PURPLE = {255, 75, 125, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::BLACK = {0, 0, 0, SDL_ALPHA_OPAQUE};
|
||||
const SDL_Color Colors::TRANSPARENCY = {0, 0, 0, SDL_ALPHA_TRANSPARENT};
|
||||
|
||||
Rect CSDL_Ext::genRect(const int & hh, const int & ww, const int & xx, const int & yy)
|
||||
{
|
||||
Rect ret;
|
||||
ret.h=hh;
|
||||
ret.w=ww;
|
||||
ret.x=xx;
|
||||
ret.y=yy;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Rect CSDL_Ext::fromSDL(const SDL_Rect & rect)
|
||||
{
|
||||
@ -79,31 +49,19 @@ SDL_Color CSDL_Ext::toSDL(const ColorRGBA & color)
|
||||
return result;
|
||||
}
|
||||
|
||||
Rect CSDL_Ext::getDisplayBounds()
|
||||
{
|
||||
SDL_Rect displayBounds;
|
||||
SDL_GetDisplayBounds(std::max(0, SDL_GetWindowDisplayIndex(mainWindow)), &displayBounds);
|
||||
|
||||
return fromSDL(displayBounds);
|
||||
}
|
||||
|
||||
void CSDL_Ext::setColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors)
|
||||
{
|
||||
SDL_SetPaletteColors(surface->format->palette,colors,firstcolor,ncolors);
|
||||
}
|
||||
|
||||
void CSDL_Ext::warpMouse(int x, int y)
|
||||
{
|
||||
SDL_WarpMouseInWindow(mainWindow,x,y);
|
||||
}
|
||||
|
||||
bool CSDL_Ext::isCtrlKeyDown()
|
||||
{
|
||||
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LCTRL] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RCTRL];
|
||||
}
|
||||
|
||||
bool CSDL_Ext::isAltKeyDown()
|
||||
{
|
||||
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LALT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RALT];
|
||||
}
|
||||
|
||||
bool CSDL_Ext::isShiftKeyDown()
|
||||
{
|
||||
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LSHIFT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RSHIFT];
|
||||
}
|
||||
|
||||
void CSDL_Ext::setAlpha(SDL_Surface * bg, int value)
|
||||
{
|
||||
SDL_SetSurfaceAlphaMod(bg, value);
|
||||
@ -122,6 +80,11 @@ void CSDL_Ext::updateRect(SDL_Surface *surface, const Rect & rect )
|
||||
|
||||
}
|
||||
|
||||
SDL_Surface * CSDL_Ext::newSurface(int w, int h)
|
||||
{
|
||||
return newSurface(w, h, screen);
|
||||
}
|
||||
|
||||
SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
|
||||
{
|
||||
SDL_Surface * ret = SDL_CreateRGBSurface(0,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
|
||||
@ -409,14 +372,6 @@ uint32_t CSDL_Ext::colorTouint32_t(const SDL_Color * color)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CSDL_Ext::update(SDL_Surface * what)
|
||||
{
|
||||
if(!what)
|
||||
return;
|
||||
if(0 !=SDL_UpdateTexture(screenTexture, nullptr, what->pixels, what->pitch))
|
||||
logGlobal->error("%s SDL_UpdateTexture %s", __FUNCTION__, SDL_GetError());
|
||||
}
|
||||
|
||||
static void drawLineX(SDL_Surface * sur, int x1, int y1, int x2, int y2, const SDL_Color & color1, const SDL_Color & color2)
|
||||
{
|
||||
for(int x = x1; x <= x2; x++)
|
||||
@ -479,23 +434,27 @@ void CSDL_Ext::drawLine(SDL_Surface * sur, int x1, int y1, int x2, int y2, const
|
||||
}
|
||||
}
|
||||
|
||||
void CSDL_Ext::drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const SDL_Color &color)
|
||||
void CSDL_Ext::drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const SDL_Color &color, int depth)
|
||||
{
|
||||
for(int i = 0; i < w; i++)
|
||||
depth = std::max(1, depth);
|
||||
for(int depthIterator = 0; depthIterator < depth; depthIterator++)
|
||||
{
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x+i,y,color.r,color.g,color.b);
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x+i,y+h-1,color.r,color.g,color.b);
|
||||
}
|
||||
for(int i = 0; i < h; i++)
|
||||
{
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x,y+i,color.r,color.g,color.b);
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x+w-1,y+i,color.r,color.g,color.b);
|
||||
for(int i = 0; i < w; i++)
|
||||
{
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x+i,y+depthIterator,color.r,color.g,color.b);
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x+i,y+h-1-depthIterator,color.r,color.g,color.b);
|
||||
}
|
||||
for(int i = 0; i < h; i++)
|
||||
{
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x+depthIterator,y+i,color.r,color.g,color.b);
|
||||
CSDL_Ext::putPixelWithoutRefreshIfInSurf(sur,x+w-1-depthIterator,y+i,color.r,color.g,color.b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSDL_Ext::drawBorder( SDL_Surface * sur, const Rect &r, const SDL_Color &color )
|
||||
void CSDL_Ext::drawBorder( SDL_Surface * sur, const Rect &r, const SDL_Color &color, int depth)
|
||||
{
|
||||
drawBorder(sur, r.x, r.y, r.w, r.h, color);
|
||||
drawBorder(sur, r.x, r.y, r.w, r.h, color, depth);
|
||||
}
|
||||
|
||||
void CSDL_Ext::drawDashedBorder(SDL_Surface * sur, const Rect &r, const SDL_Color &color)
|
||||
@ -581,15 +540,6 @@ uint8_t * CSDL_Ext::getPxPtr(const SDL_Surface * const &srf, const int x, const
|
||||
return (uint8_t *)srf->pixels + y * srf->pitch + x * srf->format->BytesPerPixel;
|
||||
}
|
||||
|
||||
std::string CSDL_Ext::processStr(std::string str, std::vector<std::string> & tor)
|
||||
{
|
||||
for (size_t i=0; (i<tor.size())&&(boost::find_first(str,"%s")); ++i)
|
||||
{
|
||||
boost::replace_first(str,"%s",tor[i]);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
bool CSDL_Ext::isTransparent( SDL_Surface * srf, const Point & position )
|
||||
{
|
||||
return isTransparent(srf, position.x, position.y);
|
||||
@ -883,59 +833,6 @@ SDL_Color CSDL_Ext::makeColor(ui8 r, ui8 g, ui8 b, ui8 a)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CSDL_Ext::startTextInput(const Rect & whereInput)
|
||||
{
|
||||
#ifdef VCMI_APPLE
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
#endif
|
||||
|
||||
// TODO ios: looks like SDL bug actually, try fixing there
|
||||
auto renderer = SDL_GetRenderer(mainWindow);
|
||||
float scaleX, scaleY;
|
||||
SDL_Rect viewport;
|
||||
SDL_RenderGetScale(renderer, &scaleX, &scaleY);
|
||||
SDL_RenderGetViewport(renderer, &viewport);
|
||||
|
||||
#ifdef VCMI_IOS
|
||||
const auto nativeScale = iOS_utils::screenScale();
|
||||
scaleX /= nativeScale;
|
||||
scaleY /= nativeScale;
|
||||
#endif
|
||||
|
||||
SDL_Rect rectInScreenCoordinates;
|
||||
rectInScreenCoordinates.x = (viewport.x + whereInput.x) * scaleX;
|
||||
rectInScreenCoordinates.y = (viewport.y + whereInput.y) * scaleY;
|
||||
rectInScreenCoordinates.w = whereInput.w * scaleX;
|
||||
rectInScreenCoordinates.h = whereInput.h * scaleY;
|
||||
|
||||
SDL_SetTextInputRect(&rectInScreenCoordinates);
|
||||
|
||||
if (SDL_IsTextInputActive() == SDL_FALSE)
|
||||
{
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSDL_Ext::stopTextInput()
|
||||
{
|
||||
#ifdef VCMI_APPLE
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
#endif
|
||||
|
||||
if (SDL_IsTextInputActive() == SDL_TRUE)
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
STRONG_INLINE static uint32_t mapColor(SDL_Surface * surface, SDL_Color color)
|
||||
{
|
||||
return SDL_MapRGBA(surface->format, color.r, color.g, color.b, color.a);
|
||||
|
@ -20,11 +20,6 @@ struct SDL_Texture;
|
||||
struct SDL_Surface;
|
||||
struct SDL_Color;
|
||||
|
||||
extern SDL_Window * mainWindow;
|
||||
extern SDL_Renderer * mainRenderer;
|
||||
extern SDL_Texture * screenTexture;
|
||||
extern SDL_Surface * screen, *screen2, *screenBuf;
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class Rect;
|
||||
@ -32,44 +27,6 @@ class Point;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
/**
|
||||
* The colors class defines color constants of type SDL_Color.
|
||||
*/
|
||||
class Colors
|
||||
{
|
||||
public:
|
||||
/** the h3 yellow color, typically used for headlines */
|
||||
static const SDL_Color YELLOW;
|
||||
|
||||
/** the standard h3 white color */
|
||||
static const SDL_Color WHITE;
|
||||
|
||||
/** the metallic gold color used mostly as a border around buttons */
|
||||
static const SDL_Color METALLIC_GOLD;
|
||||
|
||||
/** green color used for in-game console */
|
||||
static const SDL_Color GREEN;
|
||||
|
||||
/** the h3 orange color, used for blocked buttons */
|
||||
static const SDL_Color ORANGE;
|
||||
|
||||
/** the h3 bright yellow color, used for selection border */
|
||||
static const SDL_Color BRIGHT_YELLOW;
|
||||
|
||||
/** default key color for all 8 & 24 bit graphics */
|
||||
static const SDL_Color DEFAULT_KEY_COLOR;
|
||||
|
||||
/// Selected creature card
|
||||
static const SDL_Color RED;
|
||||
|
||||
/// Minimap border
|
||||
static const SDL_Color PURPLE;
|
||||
|
||||
static const SDL_Color BLACK;
|
||||
|
||||
static const SDL_Color TRANSPARENCY;
|
||||
};
|
||||
|
||||
namespace CSDL_Ext
|
||||
{
|
||||
|
||||
@ -86,39 +43,13 @@ ColorRGBA fromSDL(const SDL_Color & color);
|
||||
SDL_Color toSDL(const ColorRGBA & color);
|
||||
|
||||
void setColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors);
|
||||
void warpMouse(int x, int y);
|
||||
bool isCtrlKeyDown();
|
||||
bool isAltKeyDown();
|
||||
bool isShiftKeyDown();
|
||||
void setAlpha(SDL_Surface * bg, int value);
|
||||
|
||||
template<typename IntType>
|
||||
std::string makeNumberShort(IntType number, IntType maxLength = 3) //the output is a string containing at most 5 characters [4 if positive] (eg. intead 10000 it gives 10k)
|
||||
{
|
||||
IntType max = pow(10, maxLength);
|
||||
if (std::abs(number) < max)
|
||||
return boost::lexical_cast<std::string>(number);
|
||||
|
||||
std::string symbols = " kMGTPE";
|
||||
auto iter = symbols.begin();
|
||||
|
||||
while (number >= max)
|
||||
{
|
||||
number /= 1000;
|
||||
iter++;
|
||||
|
||||
assert(iter != symbols.end());//should be enough even for int64
|
||||
}
|
||||
return boost::lexical_cast<std::string>(number) + *iter;
|
||||
}
|
||||
|
||||
Rect genRect(const int & hh, const int & ww, const int & xx, const int & yy);
|
||||
|
||||
typedef void (*TColorPutter)(uint8_t *&ptr, const uint8_t & R, const uint8_t & G, const uint8_t & B);
|
||||
typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_t & G, const uint8_t & B, const uint8_t & A);
|
||||
|
||||
void blitAt(SDL_Surface * src, int x, int y, SDL_Surface * dst=screen);
|
||||
void blitAt(SDL_Surface * src, const Rect & pos, SDL_Surface * dst=screen);
|
||||
void blitAt(SDL_Surface * src, int x, int y, SDL_Surface * dst);
|
||||
void blitAt(SDL_Surface * src, const Rect & pos, SDL_Surface * dst);
|
||||
|
||||
void setClipRect(SDL_Surface * src, const Rect & other);
|
||||
void getClipRect(SDL_Surface * src, Rect & other);
|
||||
@ -150,14 +81,17 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
uint32_t colorTouint32_t(const SDL_Color * color); //little endian only
|
||||
SDL_Color makeColor(ui8 r, ui8 g, ui8 b, ui8 a);
|
||||
|
||||
void update(SDL_Surface * what = screen); //updates whole surface (default - main screen)
|
||||
/// returns dimensions of display on which VCMI window is located
|
||||
Rect getDisplayBounds();
|
||||
|
||||
void drawLine(SDL_Surface * sur, int x1, int y1, int x2, int y2, const SDL_Color & color1, const SDL_Color & color2);
|
||||
void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const SDL_Color &color);
|
||||
void drawBorder(SDL_Surface * sur, const Rect &r, const SDL_Color &color);
|
||||
void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const SDL_Color &color, int depth = 1);
|
||||
void drawBorder(SDL_Surface * sur, const Rect &r, const SDL_Color &color, int depth = 1);
|
||||
void drawDashedBorder(SDL_Surface * sur, const Rect &r, const SDL_Color &color);
|
||||
void setPlayerColor(SDL_Surface * sur, PlayerColor player); //sets correct color of flags; -1 for neutral
|
||||
std::string processStr(std::string str, std::vector<std::string> & tor); //replaces %s in string
|
||||
SDL_Surface * newSurface(int w, int h, SDL_Surface * mod=screen); //creates new surface, with flags/format same as in surface given
|
||||
|
||||
SDL_Surface * newSurface(int w, int h, SDL_Surface * mod); //creates new surface, with flags/format same as in surface given
|
||||
SDL_Surface * newSurface(int w, int h); //creates new surface, with flags/format same as in screen surface
|
||||
SDL_Surface * copySurface(SDL_Surface * mod); //returns copy of given surface
|
||||
template<int bpp>
|
||||
SDL_Surface * createSurfaceWithBpp(int width, int height); //create surface with give bits per pixels value
|
||||
@ -173,14 +107,10 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
void applyEffectBpp( SDL_Surface * surf, const Rect & rect, int mode );
|
||||
void applyEffect(SDL_Surface * surf, const Rect & rect, int mode); //mode: 0 - sepia, 1 - grayscale
|
||||
|
||||
void startTextInput(const Rect & where);
|
||||
void stopTextInput();
|
||||
|
||||
void setColorKey(SDL_Surface * surface, SDL_Color color);
|
||||
|
||||
///set key-color to 0,255,255
|
||||
void setDefaultColorKey(SDL_Surface * surface);
|
||||
|
||||
///set key-color to 0,255,255 only if it exactly mapped
|
||||
void setDefaultColorKeyPresize(SDL_Surface * surface);
|
||||
|
||||
|
@ -68,7 +68,7 @@ namespace Channels
|
||||
static channel_empty a;
|
||||
};
|
||||
|
||||
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
#ifdef VCMI_ENDIAN_BIG
|
||||
|
||||
template<>
|
||||
struct px<4>
|
||||
|
@ -21,12 +21,11 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
void CButton::update()
|
||||
{
|
||||
if (overlay)
|
||||
@ -555,22 +554,22 @@ void CSlider::sliderClicked()
|
||||
addUsedEvents(MOVE);
|
||||
}
|
||||
|
||||
void CSlider::mouseMoved (const SDL_MouseMotionEvent & sEvent)
|
||||
void CSlider::mouseMoved (const Point & cursorPosition)
|
||||
{
|
||||
double v = 0;
|
||||
if(horizontal)
|
||||
{
|
||||
if( std::abs(sEvent.y-(pos.y+pos.h/2)) > pos.h/2+40 || std::abs(sEvent.x-(pos.x+pos.w/2)) > pos.w/2 )
|
||||
if( std::abs(cursorPosition.y-(pos.y+pos.h/2)) > pos.h/2+40 || std::abs(cursorPosition.x-(pos.x+pos.w/2)) > pos.w/2 )
|
||||
return;
|
||||
v = sEvent.x - pos.x - 24;
|
||||
v = cursorPosition.x - pos.x - 24;
|
||||
v *= positions;
|
||||
v /= (pos.w - 48);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(std::abs(sEvent.x-(pos.x+pos.w/2)) > pos.w/2+40 || std::abs(sEvent.y-(pos.y+pos.h/2)) > pos.h/2 )
|
||||
if(std::abs(cursorPosition.x-(pos.x+pos.w/2)) > pos.w/2+40 || std::abs(cursorPosition.y-(pos.y+pos.h/2)) > pos.h/2 )
|
||||
return;
|
||||
v = sEvent.y - pos.y - 24;
|
||||
v = cursorPosition.y - pos.y - 24;
|
||||
v *= positions;
|
||||
v /= (pos.h - 48);
|
||||
}
|
||||
@ -679,7 +678,7 @@ void CSlider::clickLeft(tribool down, bool previousState)
|
||||
return;
|
||||
// if (rw>1) return;
|
||||
// if (rw<0) return;
|
||||
slider->clickLeft(true, slider->mouseState(EIntObjMouseBtnType::LEFT));
|
||||
slider->clickLeft(true, slider->mouseState(MouseButton::LEFT));
|
||||
moveTo((int)(rw * positions + 0.5));
|
||||
return;
|
||||
}
|
||||
@ -780,12 +779,10 @@ void CSlider::wheelScrolled(bool down, bool in)
|
||||
moveTo(value + 3 * (down ? +scrollStep : -scrollStep));
|
||||
}
|
||||
|
||||
void CSlider::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void CSlider::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
if(key.state != SDL_PRESSED) return;
|
||||
|
||||
int moveDest = value;
|
||||
switch(key.keysym.sym)
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_UP:
|
||||
if (!horizontal)
|
||||
|
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../gui/CIntObject.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../../lib/FunctionList.h"
|
||||
|
||||
#include <SDL_pixels.h>
|
||||
@ -270,10 +270,10 @@ public:
|
||||
|
||||
void addCallback(std::function<void(int)> callback);
|
||||
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
void wheelScrolled(bool down, bool in) override;
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override;
|
||||
void mouseMoved (const Point & cursorPosition) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
|
||||
/// @param position coordinates of slider
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "../windows/CHeroWindow.h"
|
||||
#include "../windows/CSpellWindow.h"
|
||||
#include "../windows/GUIClasses.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CGameInfo.h"
|
||||
|
||||
|
@ -14,11 +14,11 @@
|
||||
#include "TextControls.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../windows/CCreatureWindow.h"
|
||||
#include "../windows/GUIClasses.h"
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
@ -28,12 +28,6 @@
|
||||
|
||||
#include "../../lib/CGameState.h"
|
||||
|
||||
#ifdef VCMI_MAC
|
||||
#define SDL_SCANCODE_LCTRL SDL_SCANCODE_LGUI
|
||||
#endif
|
||||
|
||||
#include <SDL_keyboard.h>
|
||||
|
||||
void CGarrisonSlot::setHighlight(bool on)
|
||||
{
|
||||
if (on)
|
||||
@ -336,7 +330,7 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
||||
lastHeroStackSelected = true;
|
||||
}
|
||||
|
||||
if((owner->getSplittingMode() || LOCPLINT->shiftPressed()) // split window
|
||||
if((owner->getSplittingMode() || GH.isKeyboardShiftDown()) // split window
|
||||
&& (!creature || creature == selection->creature))
|
||||
{
|
||||
refr = split();
|
||||
@ -380,7 +374,7 @@ void CGarrisonSlot::update()
|
||||
creatureImage->setFrame(creature->getIconIndex());
|
||||
|
||||
stackCount->enable();
|
||||
stackCount->setText(CSDL_Ext::makeNumberShort(myStack->count, 4));
|
||||
stackCount->setText(vstd::formatMetric(myStack->count, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -439,10 +433,9 @@ void CGarrisonSlot::splitIntoParts(CGarrisonSlot::EGarrisonType type, int amount
|
||||
|
||||
bool CGarrisonSlot::handleSplittingShortcuts()
|
||||
{
|
||||
const uint8_t * state = SDL_GetKeyboardState(NULL);
|
||||
const bool isAlt = !!state[SDL_SCANCODE_LALT];
|
||||
const bool isLShift = !!state[SDL_SCANCODE_LSHIFT];
|
||||
const bool isLCtrl = !!state[SDL_SCANCODE_LCTRL];
|
||||
const bool isAlt = GH.isKeyboardAltDown();
|
||||
const bool isLShift = GH.isKeyboardShiftDown();
|
||||
const bool isLCtrl = GH.isKeyboardCtrlDown();
|
||||
|
||||
if(!isAlt && !isLShift && !isLCtrl)
|
||||
return false; // This is only case when return false
|
||||
|
@ -182,6 +182,18 @@ void CMinorResDataBar::show(SDL_Surface * to)
|
||||
{
|
||||
}
|
||||
|
||||
std::string CMinorResDataBar::buildDateString()
|
||||
{
|
||||
std::string pattern = "%s: %d, %s: %d, %s: %d";
|
||||
|
||||
auto formatted = boost::format(pattern)
|
||||
% CGI->generaltexth->translate("core.genrltxt.62") % LOCPLINT->cb->getDate(Date::MONTH)
|
||||
% CGI->generaltexth->translate("core.genrltxt.63") % LOCPLINT->cb->getDate(Date::WEEK)
|
||||
% CGI->generaltexth->translate("core.genrltxt.64") % LOCPLINT->cb->getDate(Date::DAY_OF_WEEK);
|
||||
|
||||
return boost::str(formatted);
|
||||
}
|
||||
|
||||
void CMinorResDataBar::showAll(SDL_Surface * to)
|
||||
{
|
||||
CIntObject::showAll(to);
|
||||
@ -192,16 +204,7 @@ void CMinorResDataBar::showAll(SDL_Surface * to)
|
||||
|
||||
graphics->fonts[FONT_SMALL]->renderTextCenter(to, text, Colors::WHITE, Point(pos.x + 50 + 76 * i, pos.y + pos.h/2));
|
||||
}
|
||||
std::vector<std::string> temp;
|
||||
|
||||
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::MONTH)));
|
||||
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::WEEK)));
|
||||
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK)));
|
||||
|
||||
std::string datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
|
||||
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
|
||||
|
||||
graphics->fonts[FONT_SMALL]->renderTextCenter(to, CSDL_Ext::processStr(datetext,temp), Colors::WHITE, Point(pos.x+545+(pos.w-545)/2,pos.y+pos.h/2));
|
||||
graphics->fonts[FONT_SMALL]->renderTextCenter(to, buildDateString(), Colors::WHITE, Point(pos.x+545+(pos.w-545)/2,pos.y+pos.h/2));
|
||||
}
|
||||
|
||||
CMinorResDataBar::CMinorResDataBar()
|
||||
@ -248,7 +251,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
|
||||
std::string subtitle;
|
||||
if(army.army.isDetailed)
|
||||
{
|
||||
subtitle = CSDL_Ext::makeNumberShort(slot.second.count, 4);
|
||||
subtitle = vstd::formatMetric(slot.second.count, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -117,6 +117,8 @@ public:
|
||||
class CMinorResDataBar : public CIntObject
|
||||
{
|
||||
std::shared_ptr<CPicture> background;
|
||||
|
||||
std::string buildDateString();
|
||||
public:
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
|
@ -17,14 +17,14 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../windows/CMessage.h"
|
||||
#include "../adventureMap/CInGameConsole.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
#include "lib/CAndroidVMHelper.h"
|
||||
#endif
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
std::list<CFocusable*> CFocusable::focusables;
|
||||
CFocusable * CFocusable::inputWithFocus;
|
||||
|
||||
@ -353,14 +353,14 @@ void CGStatusBar::setEnteringMode(bool on)
|
||||
{
|
||||
assert(enteringText == false);
|
||||
alignment = ETextAlignment::TOPLEFT;
|
||||
CSDL_Ext::startTextInput(pos);
|
||||
GH.startTextInput(pos);
|
||||
setText(consoleText);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(enteringText == true);
|
||||
alignment = ETextAlignment::CENTER;
|
||||
CSDL_Ext::stopTextInput();
|
||||
GH.stopTextInput();
|
||||
setText(hoverText);
|
||||
}
|
||||
enteringText = on;
|
||||
@ -526,7 +526,7 @@ CKeyboardFocusListener::CKeyboardFocusListener(CTextInput * textInput)
|
||||
|
||||
void CKeyboardFocusListener::focusGot()
|
||||
{
|
||||
CSDL_Ext::startTextInput(textInput->pos);
|
||||
GH.startTextInput(textInput->pos);
|
||||
usageIndex++;
|
||||
}
|
||||
|
||||
@ -534,7 +534,7 @@ void CKeyboardFocusListener::focusLost()
|
||||
{
|
||||
if(0 == --usageIndex)
|
||||
{
|
||||
CSDL_Ext::stopTextInput();
|
||||
GH.stopTextInput();
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,13 +549,12 @@ void CTextInput::clickLeft(tribool down, bool previousState)
|
||||
giveFocus();
|
||||
}
|
||||
|
||||
void CTextInput::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void CTextInput::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
|
||||
if(!focus || key.state != SDL_PRESSED)
|
||||
if(!focus)
|
||||
return;
|
||||
|
||||
if(key.keysym.sym == SDLK_TAB)
|
||||
if(key == SDLK_TAB)
|
||||
{
|
||||
moveFocus();
|
||||
GH.breakEventHandling();
|
||||
@ -564,7 +563,7 @@ void CTextInput::keyPressed(const SDL_KeyboardEvent & key)
|
||||
|
||||
bool redrawNeeded = false;
|
||||
|
||||
switch(key.keysym.sym)
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_DELETE: // have index > ' ' so it won't be filtered out by default section
|
||||
return;
|
||||
@ -603,21 +602,21 @@ void CTextInput::setText(const std::string & nText, bool callCb)
|
||||
cb(text);
|
||||
}
|
||||
|
||||
bool CTextInput::captureThisEvent(const SDL_KeyboardEvent & key)
|
||||
bool CTextInput::captureThisKey(const SDL_Keycode & key)
|
||||
{
|
||||
if(key.keysym.sym == SDLK_RETURN || key.keysym.sym == SDLK_KP_ENTER || key.keysym.sym == SDLK_ESCAPE)
|
||||
if(key == SDLK_RETURN || key == SDLK_KP_ENTER || key == SDLK_ESCAPE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTextInput::textInputed(const SDL_TextInputEvent & event)
|
||||
void CTextInput::textInputed(const std::string & enteredText)
|
||||
{
|
||||
if(!focus)
|
||||
return;
|
||||
std::string oldText = text;
|
||||
|
||||
text += event.text;
|
||||
text += enteredText;
|
||||
|
||||
filters(text, oldText);
|
||||
if(text != oldText)
|
||||
@ -628,12 +627,12 @@ void CTextInput::textInputed(const SDL_TextInputEvent & event)
|
||||
newText.clear();
|
||||
}
|
||||
|
||||
void CTextInput::textEdited(const SDL_TextEditingEvent & event)
|
||||
void CTextInput::textEdited(const std::string & enteredText)
|
||||
{
|
||||
if(!focus)
|
||||
return;
|
||||
|
||||
newText = event.text;
|
||||
newText = enteredText;
|
||||
redraw();
|
||||
cb(text + newText);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "../gui/CIntObject.h"
|
||||
#include "../gui/TextAlignment.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
#include "../render/Colors.h"
|
||||
#include "../render/Graphics.h"
|
||||
#include "../../lib/FunctionList.h"
|
||||
|
||||
@ -225,11 +225,12 @@ public:
|
||||
CTextInput(const Rect & Pos, std::shared_ptr<IImage> srf);
|
||||
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
bool captureThisEvent(const SDL_KeyboardEvent & key) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
|
||||
void textInputed(const SDL_TextInputEvent & event) override;
|
||||
void textEdited(const SDL_TextEditingEvent & event) override;
|
||||
bool captureThisKey(const SDL_Keycode & key) override;
|
||||
|
||||
void textInputed(const std::string & enteredText) override;
|
||||
void textEdited(const std::string & enteredText) override;
|
||||
|
||||
//Filter that will block all characters not allowed in filenames
|
||||
static void filenameFilter(std::string & text, const std::string & oldText);
|
||||
|
@ -102,7 +102,7 @@ BattleOptionsWindow::BattleOptionsWindow(BattleInterface * owner):
|
||||
int BattleOptionsWindow::getAnimSpeed() const
|
||||
{
|
||||
if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-battle-speed"].isNull())
|
||||
return static_cast<int>(vstd::round(settings["session"]["spectate-battle-speed"].Float()));
|
||||
return static_cast<int>(std::round(settings["session"]["spectate-battle-speed"].Float()));
|
||||
|
||||
return static_cast<int>(vstd::round(settings["battle"]["speedFactor"].Float()));
|
||||
return static_cast<int>(std::round(settings["battle"]["speedFactor"].Float()));
|
||||
}
|
@ -43,7 +43,6 @@
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town, const CStructure * Str)
|
||||
: CShowableAnim(0, 0, Str->defName, CShowableAnim::BASE, BUILDING_FRAME_TIME),
|
||||
@ -146,7 +145,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
|
||||
else
|
||||
{
|
||||
int level = ( bid - BuildingID::DWELL_FIRST ) % GameConstants::CREATURES_PER_TOWN;
|
||||
GH.pushIntT<CDwellingInfoBox>(parent->pos.x+parent->pos.w/2, parent->pos.y+parent->pos.h/2, town, level);
|
||||
GH.pushIntT<CDwellingInfoBox>(parent->pos.x+parent->pos.w / 2, parent->pos.y+parent->pos.h /2, town, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,11 +240,11 @@ std::string CBuildingRect::getSubtitle()//hover text for building
|
||||
}
|
||||
}
|
||||
|
||||
void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
|
||||
void CBuildingRect::mouseMoved (const Point & cursorPosition)
|
||||
{
|
||||
if(area && pos.isInside(sEvent.x, sEvent.y))
|
||||
if(area && pos.isInside(cursorPosition.x, cursorPosition.y))
|
||||
{
|
||||
if(area->isTransparent(GH.getCursorPosition() - pos.topLeft())) //hovered pixel is inside this building
|
||||
if(area->isTransparent(cursorPosition - pos.topLeft())) //hovered pixel is inside this building
|
||||
{
|
||||
if(parent->selectedBuilding == this)
|
||||
{
|
||||
@ -1066,7 +1065,7 @@ void CCreaInfo::clickRight(tribool down, bool previousState)
|
||||
if(down)
|
||||
{
|
||||
if (showAvailable)
|
||||
GH.pushIntT<CDwellingInfoBox>(screen->w/2, screen->h/2, town, level);
|
||||
GH.pushIntT<CDwellingInfoBox>(GH.screenDimensions().x / 2, GH.screenDimensions().y / 2, town, level);
|
||||
else
|
||||
CRClickPopup::createAndPush(genGrowthText(), std::make_shared<CComponent>(CComponent::creature, creature->idNumber));
|
||||
}
|
||||
@ -1255,11 +1254,9 @@ void CCastleInterface::recreateIcons()
|
||||
creainfo.push_back(std::make_shared<CCreaInfo>(Point(14+55*(int)i, 507), town, (int)i+4));
|
||||
}
|
||||
|
||||
void CCastleInterface::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void CCastleInterface::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
if(key.state != SDL_PRESSED) return;
|
||||
|
||||
switch(key.keysym.sym)
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_UP:
|
||||
townlist->selectPrev();
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
void hover(bool on) override;
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override;
|
||||
void mouseMoved (const Point & cursorPosition) override;
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
};
|
||||
@ -245,7 +245,8 @@ public:
|
||||
|
||||
void castleTeleport(int where);
|
||||
void townChange();
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
|
||||
void close();
|
||||
void addBuilding(BuildingID bid);
|
||||
void removeBuilding(BuildingID bid);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/ObjectLists.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CStack.h"
|
||||
@ -31,8 +32,6 @@
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/CGameState.h"
|
||||
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
class CCreatureArtifactInstance;
|
||||
class CSelectableSkill;
|
||||
|
||||
@ -518,8 +517,8 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s
|
||||
|
||||
const CStack * battleStack = parent->info->stack;
|
||||
|
||||
morale = std::make_shared<MoraleLuckBox>(true, genRect(42, 42, 321, 110));
|
||||
luck = std::make_shared<MoraleLuckBox>(false, genRect(42, 42, 375, 110));
|
||||
morale = std::make_shared<MoraleLuckBox>(true, Rect(Point(321, 110), Point(42, 42) ));
|
||||
luck = std::make_shared<MoraleLuckBox>(false, Rect(Point(375, 110), Point(42, 42) ));
|
||||
|
||||
if(battleStack != nullptr) // in battle
|
||||
{
|
||||
@ -583,7 +582,7 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s
|
||||
}
|
||||
expLabel = std::make_shared<CLabel>(
|
||||
pos.x + 21, pos.y + 52, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE,
|
||||
makeNumberShort<TExpType>(stack->experience, 6));
|
||||
vstd::formatMetric(stack->experience, 6));
|
||||
}
|
||||
|
||||
if(showArt)
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "GUIClasses.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMT.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "InfoWindows.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMT.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
|
@ -18,8 +18,10 @@
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../render/IImage.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include <SDL_surface.h>
|
||||
|
||||
@ -210,8 +212,8 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, PlayerColor play
|
||||
assert(ret && ret->text);
|
||||
for(int i = 0;
|
||||
i < ARRAY_COUNT(sizes)
|
||||
&& sizes[i][0] < screen->w - 150
|
||||
&& sizes[i][1] < screen->h - 150
|
||||
&& sizes[i][0] < GH.screenDimensions().x - 150
|
||||
&& sizes[i][1] < GH.screenDimensions().y - 150
|
||||
&& ret->text->slider;
|
||||
i++)
|
||||
{
|
||||
@ -253,7 +255,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, PlayerColor play
|
||||
vstd::amax(winSize.first, comps.w);
|
||||
vstd::amax(winSize.first, bw);
|
||||
|
||||
vstd::amin(winSize.first, screen->w - 150);
|
||||
vstd::amin(winSize.first, GH.screenDimensions().x - 150);
|
||||
|
||||
ret->bitmap = drawDialogBox (winSize.first + 2*SIDE_MARGIN, winSize.second + 2*SIDE_MARGIN, player);
|
||||
ret->pos.h=ret->bitmap->h;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "../adventureMap/CAdvMapInt.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../adventureMap/CMinimap.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CArtHandler.h"
|
||||
|
@ -66,7 +66,7 @@ class CQuestMinimap : public CMinimap
|
||||
|
||||
void clickLeft(tribool down, bool previousState) override{}; //minimap ignores clicking on its surface
|
||||
void iconClicked();
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override{};
|
||||
void mouseMoved (const Point & cursorPosition) override{};
|
||||
|
||||
public:
|
||||
const QuestInfo * currentQuest;
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "CCastleInterface.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMT.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CVideoHandler.h"
|
||||
|
||||
@ -28,6 +27,7 @@
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../adventureMap/CAdvMapInt.h"
|
||||
#include "../render/CAnimation.h"
|
||||
#include "../renderSDL/SDL_Extensions.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
@ -39,8 +39,6 @@
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
CSpellWindow::InteractiveArea::InteractiveArea(const Rect & myRect, std::function<void()> funcL, int helpTextId, CSpellWindow * _owner)
|
||||
{
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||
@ -185,38 +183,25 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
|
||||
mana = std::make_shared<CLabel>(435, 426, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, boost::lexical_cast<std::string>(myHero->mana));
|
||||
statusBar = CGStatusBar::create(7, 569, "Spelroll.bmp");
|
||||
|
||||
Rect temp_rect = CSDL_Ext::genRect(45, 35, 479 + pos.x, 405 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fexitb, this), 460, this));
|
||||
temp_rect = CSDL_Ext::genRect(45, 35, 221 + pos.x, 405 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fbattleSpellsb, this), 453, this));
|
||||
temp_rect = CSDL_Ext::genRect(45, 35, 355 + pos.x, 405 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fadvSpellsb, this), 452, this));
|
||||
temp_rect = CSDL_Ext::genRect(45, 35, 418 + pos.x, 405 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fmanaPtsb, this), 459, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 479 + pos.x, 405 + pos.y, 36, 56), std::bind(&CSpellWindow::fexitb, this), 460, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 221 + pos.x, 405 + pos.y, 36, 56), std::bind(&CSpellWindow::fbattleSpellsb, this), 453, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 355 + pos.x, 405 + pos.y, 36, 56), std::bind(&CSpellWindow::fadvSpellsb, this), 452, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 418 + pos.x, 405 + pos.y, 36, 56), std::bind(&CSpellWindow::fmanaPtsb, this), 459, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 549 + pos.x, 94 + pos.y, 36, 56), std::bind(&CSpellWindow::selectSchool, this, 0), 454, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 549 + pos.x, 151 + pos.y, 45, 35), std::bind(&CSpellWindow::selectSchool, this, 3), 457, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 549 + pos.x, 210 + pos.y, 45, 35), std::bind(&CSpellWindow::selectSchool, this, 1), 455, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 549 + pos.x, 270 + pos.y, 45, 35), std::bind(&CSpellWindow::selectSchool, this, 2), 456, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 549 + pos.x, 330 + pos.y, 45, 35), std::bind(&CSpellWindow::selectSchool, this, 4), 458, this));
|
||||
|
||||
temp_rect = CSDL_Ext::genRect(36, 56, 549 + pos.x, 94 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 0), 454, this));
|
||||
temp_rect = CSDL_Ext::genRect(36, 56, 549 + pos.x, 151 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 3), 457, this));
|
||||
temp_rect = CSDL_Ext::genRect(36, 56, 549 + pos.x, 210 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 1), 455, this));
|
||||
temp_rect = CSDL_Ext::genRect(36, 56, 549 + pos.x, 270 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 2), 456, this));
|
||||
temp_rect = CSDL_Ext::genRect(36, 56, 549 + pos.x, 330 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 4), 458, this));
|
||||
|
||||
temp_rect = CSDL_Ext::genRect(leftCorner->pos.h, leftCorner->pos.w, 97 + pos.x, 77 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fLcornerb, this), 450, this));
|
||||
temp_rect = CSDL_Ext::genRect(rightCorner->pos.h, rightCorner->pos.w, 487 + pos.x, 72 + pos.y);
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fRcornerb, this), 451, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 97 + pos.x, 77 + pos.y, leftCorner->pos.h, leftCorner->pos.w ), std::bind(&CSpellWindow::fLcornerb, this), 450, this));
|
||||
interactiveAreas.push_back(std::make_shared<InteractiveArea>( Rect( 487 + pos.x, 72 + pos.y, rightCorner->pos.h, rightCorner->pos.w ), std::bind(&CSpellWindow::fRcornerb, this), 451, this));
|
||||
|
||||
//areas for spells
|
||||
int xpos = 117 + pos.x, ypos = 90 + pos.y;
|
||||
|
||||
for(int v=0; v<12; ++v)
|
||||
{
|
||||
temp_rect = CSDL_Ext::genRect(65, 78, xpos, ypos);
|
||||
spellAreas[v] = std::make_shared<SpellArea>(temp_rect, this);
|
||||
spellAreas[v] = std::make_shared<SpellArea>( Rect(xpos, ypos, 65, 78), this);
|
||||
|
||||
if(v == 5) //to right page
|
||||
{
|
||||
@ -422,17 +407,16 @@ void CSpellWindow::turnPageRight()
|
||||
CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15);
|
||||
}
|
||||
|
||||
void CSpellWindow::keyPressed(const SDL_KeyboardEvent & key)
|
||||
void CSpellWindow::keyPressed(const SDL_Keycode & key)
|
||||
{
|
||||
if(key.keysym.sym == SDLK_ESCAPE || key.keysym.sym == SDLK_RETURN)
|
||||
if(key == SDLK_ESCAPE || key == SDLK_RETURN)
|
||||
{
|
||||
fexitb();
|
||||
return;
|
||||
}
|
||||
|
||||
if(key.state == SDL_PRESSED)
|
||||
else
|
||||
{
|
||||
switch(key.keysym.sym)
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_LEFT:
|
||||
fLcornerb();
|
||||
@ -443,7 +427,7 @@ void CSpellWindow::keyPressed(const SDL_KeyboardEvent & key)
|
||||
case SDLK_UP:
|
||||
case SDLK_DOWN:
|
||||
{
|
||||
bool down = key.keysym.sym == SDLK_DOWN;
|
||||
bool down = key == SDLK_DOWN;
|
||||
static const int schoolsOrder[] = { 0, 3, 1, 2, 4 };
|
||||
int index = -1;
|
||||
while(schoolsOrder[++index] != selectedTab);
|
||||
@ -464,9 +448,9 @@ void CSpellWindow::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
|
||||
//alt + 1234567890-= casts spell from 1 - 12 slot
|
||||
if(myInt->altPressed())
|
||||
if(GH.isKeyboardAltDown())
|
||||
{
|
||||
SDL_Keycode hlpKey = key.keysym.sym;
|
||||
SDL_Keycode hlpKey = key;
|
||||
if(CGuiHandler::isNumKey(hlpKey, false))
|
||||
{
|
||||
if(hlpKey == SDLK_KP_PLUS)
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
void selectSchool(int school); //schools: 0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic, 4 - all schools
|
||||
int pagesWithinCurrentTab();
|
||||
|
||||
void keyPressed(const SDL_KeyboardEvent & key) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
|
||||
void show(SDL_Surface * to) override;
|
||||
};
|
||||
|
@ -504,9 +504,13 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
|
||||
|
||||
const std::vector<Rect> tmp =
|
||||
{
|
||||
CSDL_Ext::genRect(h, w, x, y), CSDL_Ext::genRect(h, w, x + dx, y), CSDL_Ext::genRect(h, w, x + 2*dx, y),
|
||||
CSDL_Ext::genRect(h, w, x, y + dy), CSDL_Ext::genRect(h, w, x + dx, y + dy), CSDL_Ext::genRect(h, w, x + 2*dx, y + dy),
|
||||
CSDL_Ext::genRect(h, w, x + dx, y + 2*dy)
|
||||
Rect(Point(x + 0 * dx, y + 0 * dx), Point(h, w) ),
|
||||
Rect(Point(x + 1 * dx, y + 0 * dx), Point(h, w) ),
|
||||
Rect(Point(x + 2 * dx, y + 0 * dx), Point(h, w) ),
|
||||
Rect(Point(x + 0 * dx, y + 1 * dy), Point(h, w) ),
|
||||
Rect(Point(x + 1 * dx, y + 1 * dy), Point(h, w) ),
|
||||
Rect(Point(x + 2 * dx, y + 1 * dy), Point(h, w) ),
|
||||
Rect(Point(x + 1 * dx, y + 2 * dy), Point(h, w) )
|
||||
};
|
||||
|
||||
vstd::concatenate(poss, tmp);
|
||||
|
@ -69,7 +69,7 @@ CWindowObject::CWindowObject(int options_, std::string imageName):
|
||||
if(background)
|
||||
pos = background->center();
|
||||
else
|
||||
center(Point(screen->w/2, screen->h/2));
|
||||
center(GH.screenDimensions() / 2);
|
||||
|
||||
if(!(options & SHADOW_DISABLED))
|
||||
setShadow(true);
|
||||
|
@ -63,10 +63,6 @@
|
||||
#include "../lib/NetPacksBase.h"
|
||||
#include "../lib/StartInfo.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
CRecruitmentWindow::CCreatureCard::CCreatureCard(CRecruitmentWindow * window, const CCreature * crea, int totalAmount)
|
||||
: CIntObject(LCLICK | RCLICK),
|
||||
parent(window),
|
||||
@ -103,9 +99,9 @@ void CRecruitmentWindow::CCreatureCard::showAll(SDL_Surface * to)
|
||||
{
|
||||
CIntObject::showAll(to);
|
||||
if(selected)
|
||||
drawBorder(to, pos, Colors::RED);
|
||||
CSDL_Ext::drawBorder(to, pos, Colors::RED);
|
||||
else
|
||||
drawBorder(to, pos, Colors::YELLOW);
|
||||
CSDL_Ext::drawBorder(to, pos, Colors::YELLOW);
|
||||
}
|
||||
|
||||
void CRecruitmentWindow::select(std::shared_ptr<CCreatureCard> card)
|
||||
@ -180,17 +176,17 @@ void CRecruitmentWindow::showAll(SDL_Surface * to)
|
||||
CWindowObject::showAll(to);
|
||||
|
||||
// recruit\total values
|
||||
drawBorder(to, pos.x + 172, pos.y + 222, 67, 42, Colors::YELLOW);
|
||||
drawBorder(to, pos.x + 246, pos.y + 222, 67, 42, Colors::YELLOW);
|
||||
CSDL_Ext::drawBorder(to, pos.x + 172, pos.y + 222, 67, 42, Colors::YELLOW);
|
||||
CSDL_Ext::drawBorder(to, pos.x + 246, pos.y + 222, 67, 42, Colors::YELLOW);
|
||||
|
||||
//cost boxes
|
||||
drawBorder(to, pos.x + 64, pos.y + 222, 99, 76, Colors::YELLOW);
|
||||
drawBorder(to, pos.x + 322, pos.y + 222, 99, 76, Colors::YELLOW);
|
||||
CSDL_Ext::drawBorder(to, pos.x + 64, pos.y + 222, 99, 76, Colors::YELLOW);
|
||||
CSDL_Ext::drawBorder(to, pos.x + 322, pos.y + 222, 99, 76, Colors::YELLOW);
|
||||
|
||||
//buttons borders
|
||||
drawBorder(to, pos.x + 133, pos.y + 312, 66, 34, Colors::METALLIC_GOLD);
|
||||
drawBorder(to, pos.x + 211, pos.y + 312, 66, 34, Colors::METALLIC_GOLD);
|
||||
drawBorder(to, pos.x + 289, pos.y + 312, 66, 34, Colors::METALLIC_GOLD);
|
||||
CSDL_Ext::drawBorder(to, pos.x + 133, pos.y + 312, 66, 34, Colors::METALLIC_GOLD);
|
||||
CSDL_Ext::drawBorder(to, pos.x + 211, pos.y + 312, 66, 34, Colors::METALLIC_GOLD);
|
||||
CSDL_Ext::drawBorder(to, pos.x + 289, pos.y + 312, 66, 34, Colors::METALLIC_GOLD);
|
||||
}
|
||||
|
||||
CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, const CArmedInstance * Dst, const std::function<void(CreatureID,int)> & Recruit, int y_offset):
|
||||
@ -921,9 +917,9 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
{
|
||||
primSkillAreas.push_back(std::make_shared<LRClickableAreaWTextComp>());
|
||||
if (qeLayout)
|
||||
primSkillAreas[g]->pos = genRect(22, 152, pos.x + 324, pos.y + 12 + 26 * g);
|
||||
primSkillAreas[g]->pos = Rect(Point(pos.x + 324, pos.y + 12 + 26 * g), Point(22, 152));
|
||||
else
|
||||
primSkillAreas[g]->pos = genRect(32, 140, pos.x + 329, pos.y + 19 + 36 * g);
|
||||
primSkillAreas[g]->pos = Rect(Point(pos.x + 329, pos.y + 19 + 36 * g), Point(32, 140));
|
||||
primSkillAreas[g]->text = CGI->generaltexth->arraytxt[2+g];
|
||||
primSkillAreas[g]->type = g;
|
||||
primSkillAreas[g]->bonusValue = -1;
|
||||
@ -943,7 +939,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
int skill = hero->secSkills[g].first,
|
||||
level = hero->secSkills[g].second; // <1, 3>
|
||||
secSkillAreas[b].push_back(std::make_shared<LRClickableAreaWTextComp>());
|
||||
secSkillAreas[b][g]->pos = genRect(32, 32, pos.x + 32 + g*36 + b*454 , pos.y + (qeLayout ? 83 : 88));
|
||||
secSkillAreas[b][g]->pos = Rect(Point(pos.x + 32 + g * 36 + b * 454 , pos.y + (qeLayout ? 83 : 88)), Point(32, 32) );
|
||||
secSkillAreas[b][g]->baseType = 1;
|
||||
|
||||
secSkillAreas[b][g]->type = skill;
|
||||
@ -958,12 +954,12 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
heroAreas[b] = std::make_shared<CHeroArea>(257 + 228*b, 13, hero);
|
||||
|
||||
specialtyAreas[b] = std::make_shared<LRClickableAreaWText>();
|
||||
specialtyAreas[b]->pos = genRect(32, 32, pos.x + 69 + 490*b, pos.y + (qeLayout ? 41 : 45));
|
||||
specialtyAreas[b]->pos = Rect(Point(pos.x + 69 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
|
||||
specialtyAreas[b]->hoverText = CGI->generaltexth->heroscrn[27];
|
||||
specialtyAreas[b]->text = hero->type->getSpecialtyDescriptionTranslated();
|
||||
|
||||
experienceAreas[b] = std::make_shared<LRClickableAreaWText>();
|
||||
experienceAreas[b]->pos = genRect(32, 32, pos.x + 105 + 490*b, pos.y + (qeLayout ? 41 : 45));
|
||||
experienceAreas[b]->pos = Rect(Point(pos.x + 105 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
|
||||
experienceAreas[b]->hoverText = CGI->generaltexth->heroscrn[9];
|
||||
experienceAreas[b]->text = CGI->generaltexth->allTexts[2];
|
||||
boost::algorithm::replace_first(experienceAreas[b]->text, "%d", boost::lexical_cast<std::string>(hero->level));
|
||||
@ -971,15 +967,15 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
||||
boost::algorithm::replace_first(experienceAreas[b]->text, "%d", boost::lexical_cast<std::string>(hero->exp));
|
||||
|
||||
spellPointsAreas[b] = std::make_shared<LRClickableAreaWText>();
|
||||
spellPointsAreas[b]->pos = genRect(32, 32, pos.x + 141 + 490*b, pos.y + (qeLayout ? 41 : 45));
|
||||
spellPointsAreas[b]->pos = Rect(Point(pos.x + 141 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
|
||||
spellPointsAreas[b]->hoverText = CGI->generaltexth->heroscrn[22];
|
||||
spellPointsAreas[b]->text = CGI->generaltexth->allTexts[205];
|
||||
boost::algorithm::replace_first(spellPointsAreas[b]->text, "%s", hero->getNameTranslated());
|
||||
boost::algorithm::replace_first(spellPointsAreas[b]->text, "%d", boost::lexical_cast<std::string>(hero->mana));
|
||||
boost::algorithm::replace_first(spellPointsAreas[b]->text, "%d", boost::lexical_cast<std::string>(hero->manaLimit()));
|
||||
|
||||
morale[b] = std::make_shared<MoraleLuckBox>(true, genRect(32, 32, 176 + 490 * b, 39), true);
|
||||
luck[b] = std::make_shared<MoraleLuckBox>(false, genRect(32, 32, 212 + 490 * b, 39), true);
|
||||
morale[b] = std::make_shared<MoraleLuckBox>(true, Rect(Point(176 + 490 * b, 39), Point(32, 32)), true);
|
||||
luck[b] = std::make_shared<MoraleLuckBox>(false, Rect(Point(212 + 490 * b, 39), Point(32, 32)), true);
|
||||
}
|
||||
|
||||
quit = std::make_shared<CButton>(Point(732, 567), "IOKAY.DEF", CGI->generaltexth->zelp[600], std::bind(&CExchangeWindow::close, this), SDLK_RETURN);
|
||||
@ -1067,8 +1063,8 @@ void CExchangeWindow::updateWidgets()
|
||||
secSkillIcons[leftRight][m]->setFrame(2 + id * 3 + level);
|
||||
}
|
||||
|
||||
expValues[leftRight]->setText(makeNumberShort(hero->exp));
|
||||
manaValues[leftRight]->setText(makeNumberShort(hero->mana));
|
||||
expValues[leftRight]->setText(vstd::formatMetric(hero->exp, 3));
|
||||
manaValues[leftRight]->setText(vstd::formatMetric(hero->mana, 3));
|
||||
|
||||
morale[leftRight]->set(hero);
|
||||
luck[leftRight]->set(hero);
|
||||
@ -1161,7 +1157,7 @@ CPuzzleWindow::CPuzzleWindow(const int3 & GrailPos, double discoveredRatio)
|
||||
void CPuzzleWindow::showAll(SDL_Surface * to)
|
||||
{
|
||||
int3 moveInt = int3(8, 9, 0);
|
||||
Rect mapRect = genRect(544, 591, pos.x + 8, pos.y + 7);
|
||||
Rect mapRect = Rect(Point(pos.x + 8, pos.y + 7), Point(544, 591));
|
||||
int3 topTile = grailPos - moveInt;
|
||||
|
||||
MapDrawingInfo info(topTile, LOCPLINT->cb->getVisibilityMap(), mapRect);
|
||||
@ -1951,14 +1947,11 @@ void CObjectListWindow::changeSelection(size_t which)
|
||||
selected = which;
|
||||
}
|
||||
|
||||
void CObjectListWindow::keyPressed (const SDL_KeyboardEvent & key)
|
||||
void CObjectListWindow::keyPressed (const SDL_Keycode & key)
|
||||
{
|
||||
if(key.state != SDL_PRESSED)
|
||||
return;
|
||||
|
||||
int sel = static_cast<int>(selected);
|
||||
|
||||
switch(key.keysym.sym)
|
||||
switch(key)
|
||||
{
|
||||
break; case SDLK_UP:
|
||||
sel -=1;
|
||||
|
@ -43,6 +43,8 @@ class CTextBox;
|
||||
class CResDataBar;
|
||||
class CHeroWithMaybePickedArtifact;
|
||||
|
||||
enum class EUserEvent;
|
||||
|
||||
/// Recruitment window where you can recruit creatures
|
||||
class CRecruitmentWindow : public CStatusbarWindow
|
||||
{
|
||||
@ -193,7 +195,7 @@ public:
|
||||
std::shared_ptr<CIntObject> genItem(size_t index);
|
||||
void elementSelected();//call callback and close this window
|
||||
void changeSelection(size_t which);
|
||||
void keyPressed (const SDL_KeyboardEvent & key) override;
|
||||
void keyPressed(const SDL_Keycode & key) override;
|
||||
};
|
||||
|
||||
class CTavernWindow : public CStatusbarWindow
|
||||
|
@ -245,8 +245,8 @@ CInfoPopup::CInfoPopup(SDL_Surface *Bitmap, bool Free)
|
||||
|
||||
if(bitmap)
|
||||
{
|
||||
pos.x = screen->w/2 - bitmap->w/2;
|
||||
pos.y = screen->h/2 - bitmap->h/2;
|
||||
pos.x = GH.screenDimensions().x / 2 - bitmap->w / 2;
|
||||
pos.y = GH.screenDimensions().y / 2 - bitmap->h / 2;
|
||||
pos.h = bitmap->h;
|
||||
pos.w = bitmap->w;
|
||||
}
|
||||
@ -281,8 +281,8 @@ void CInfoPopup::init(int x, int y)
|
||||
// Put the window back on screen if necessary
|
||||
vstd::amax(pos.x, 0);
|
||||
vstd::amax(pos.y, 0);
|
||||
vstd::amin(pos.x, screen->w - bitmap->w);
|
||||
vstd::amin(pos.y, screen->h - bitmap->h);
|
||||
vstd::amin(pos.x, GH.screenDimensions().x - bitmap->w);
|
||||
vstd::amin(pos.y, GH.screenDimensions().y - bitmap->h);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "VcmiSettingsWindow.h"
|
||||
#include "GUIClasses.h"
|
||||
#include "CServerHandler.h"
|
||||
#include "renderSDL/SDL_Extensions.h"
|
||||
|
||||
|
||||
static void setIntSetting(std::string group, std::string field, int value)
|
||||
@ -110,8 +111,7 @@ void SystemOptionsWindow::selectGameResolution()
|
||||
std::vector<std::string> items;
|
||||
|
||||
#ifndef VCMI_IOS
|
||||
SDL_Rect displayBounds;
|
||||
SDL_GetDisplayBounds(std::max(0, SDL_GetWindowDisplayIndex(mainWindow)), &displayBounds);
|
||||
Rect displayBounds = CSDL_Ext::getDisplayBounds();
|
||||
#endif
|
||||
|
||||
size_t currentResolutionIndex = 0;
|
||||
|
@ -239,8 +239,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/../include/vcmi/Environment.h
|
||||
${MAIN_LIB_DIR}/../include/vcmi/Services.h
|
||||
|
||||
${MAIN_LIB_DIR}/abilities/Ability.h
|
||||
|
||||
${MAIN_LIB_DIR}/battle/AccessibilityInfo.h
|
||||
${MAIN_LIB_DIR}/battle/BattleAction.h
|
||||
${MAIN_LIB_DIR}/battle/BattleAttackInfo.h
|
||||
@ -477,7 +475,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
PUBLIC ${MAIN_LIB_DIR}/..
|
||||
PUBLIC ${MAIN_LIB_DIR}/../include
|
||||
PUBLIC ${MAIN_LIB_DIR}
|
||||
PRIVATE ${SDL2_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
@ -10,4 +10,4 @@ add_definitions(
|
||||
set(APP_SHORT_VERSION "${VCMI_VERSION_MAJOR}.${VCMI_VERSION_MINOR}")
|
||||
if(NOT VCMI_VERSION_PATCH EQUAL 0)
|
||||
string(APPEND APP_SHORT_VERSION ".${VCMI_VERSION_PATCH}")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -213,8 +213,9 @@
|
||||
"specialty" : {
|
||||
"bonuses" : {
|
||||
"fortune" : {
|
||||
"addInfo" : 3,
|
||||
"subtype" : "spell.fortune",
|
||||
"type" : "MAXED_SPELL"
|
||||
"type" : "SPECIAL_FIXED_VALUE_ENCHANT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
debian/changelog
vendored
8
debian/changelog
vendored
@ -2,8 +2,14 @@ vcmi (1.2.0) jammy; urgency=medium
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- Ivan Savenko <saven.ivan@gmail.com> Fri, 23 Dec 2022 16:00:00 +0200
|
||||
-- Ivan Savenko <saven.ivan@gmail.com> Sat, 04 Feb 2023 16:00:00 +0200
|
||||
|
||||
vcmi (1.1.1) jammy; urgency=medium
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- Ivan Savenko <saven.ivan@gmail.com> Fri, 03 Feb 2023 12:00:00 +0200
|
||||
|
||||
vcmi (1.1.0) jammy; urgency=medium
|
||||
|
||||
* New upstream release
|
||||
|
@ -5,8 +5,8 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
namespace vstd
|
||||
{
|
||||
|
||||
DLL_LINKAGE std::vector<std::string> split(std::string s, std::string separators);
|
||||
DLL_LINKAGE std::pair<std::string, std::string> splitStringToPair(std::string input, char separator);
|
||||
DLL_LINKAGE std::vector<std::string> split(std::string s, const std::string& separators);
|
||||
DLL_LINKAGE std::pair<std::string, std::string> splitStringToPair(const std::string& input, char separator);
|
||||
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,8 @@
|
||||
<url type="bugtracker">https://github.com/vcmi/vcmi/issues</url>
|
||||
<url type="faq">https://vcmi.eu/faq/</url>
|
||||
<releases>
|
||||
<release version="1.2.0" date="2022-12-24" type="development" />
|
||||
<release version="1.2.0" date="2023-02-04" type="development" />
|
||||
<release version="1.1.1" date="2023-02-03" />
|
||||
<release version="1.1.0" date="2022-12-23" />
|
||||
<release version="1.0.0" date="2022-09-11" />
|
||||
<release version="0.99" date="2016-11-01" />
|
||||
|
@ -611,8 +611,9 @@ std::vector<std::shared_ptr<Bonus>> SpecialtyInfoToBonuses(const SSpecialtyInfo
|
||||
result.push_back(bonus);
|
||||
break;
|
||||
case 7: //maxed mastery for spell
|
||||
bonus->type = Bonus::MAXED_SPELL;
|
||||
bonus->type = Bonus::SPECIAL_FIXED_VALUE_ENCHANT;
|
||||
bonus->subtype = spec.subtype; //spell id
|
||||
bonus->val = 3; //to match MAXED_BONUS
|
||||
result.push_back(bonus);
|
||||
break;
|
||||
case 8: //peculiar spells - enchantments
|
||||
|
@ -285,7 +285,7 @@ public:
|
||||
BONUS_NAME(SPELL_DAMAGE) /*val = value*/\
|
||||
BONUS_NAME(SPECIFIC_SPELL_DAMAGE) /*subtype = id of spell, val = value*/\
|
||||
BONUS_NAME(SPECIAL_BLESS_DAMAGE) /*val = spell (bless), additionalInfo = value per level in percent*/\
|
||||
BONUS_NAME(MAXED_SPELL) /*val = id*/\
|
||||
BONUS_NAME(MAXED_SPELL) /*val = id. deprecated in favour of SPECIAL_FIXED_VALUE_ENCHANT*/\
|
||||
BONUS_NAME(SPECIAL_PECULIAR_ENCHANT) /*blesses and curses with id = val dependent on unit's level, subtype = 0 or 1 for Coronius*/\
|
||||
BONUS_NAME(SPECIAL_UPGRADE) /*subtype = base, additionalInfo = target */\
|
||||
BONUS_NAME(DRAGON_NATURE) \
|
||||
|
@ -281,7 +281,6 @@
|
||||
<Unit filename="VCMIDirs.h" />
|
||||
<Unit filename="VCMI_Lib.cpp" />
|
||||
<Unit filename="VCMI_Lib.h" />
|
||||
<Unit filename="abilities/Ability.h" />
|
||||
<Unit filename="battle/AccessibilityInfo.cpp" />
|
||||
<Unit filename="battle/AccessibilityInfo.h" />
|
||||
<Unit filename="battle/BattleAction.cpp" />
|
||||
|
@ -39,6 +39,10 @@ struct DLL_LINKAGE BattleHex //TODO: decide if this should be changed to class f
|
||||
static const si16 CASTLE_BOTTOM_TOWER = -3;
|
||||
static const si16 CASTLE_UPPER_TOWER = -4;
|
||||
|
||||
// hexes for interaction with heroes
|
||||
static const si16 HERO_ATTACKER = 0;
|
||||
static const si16 HERO_DEFENDER = GameConstants::BFIELD_WIDTH - 1;
|
||||
|
||||
// helpers for rendering
|
||||
static const si16 HEX_BEFORE_ALL = std::numeric_limits<si16>::min();
|
||||
static const si16 HEX_AFTER_ALL = std::numeric_limits<si16>::max();
|
||||
|
@ -44,13 +44,28 @@ struct DLL_LINKAGE AttackableTiles
|
||||
|
||||
enum class PossiblePlayerBattleAction // actions performed at l-click
|
||||
{
|
||||
INVALID = -1, CREATURE_INFO,
|
||||
MOVE_TACTICS, CHOOSE_TACTICS_STACK,
|
||||
MOVE_STACK, ATTACK, WALK_AND_ATTACK, ATTACK_AND_RETURN, SHOOT, //OPEN_GATE, //we can open castle gate during siege
|
||||
NO_LOCATION, ANY_LOCATION, OBSTACLE, TELEPORT, SACRIFICE, RANDOM_GENIE_SPELL,
|
||||
FREE_LOCATION, //used with Force Field and Fire Wall - all tiles affected by spell must be free
|
||||
CATAPULT, HEAL,
|
||||
AIMED_SPELL_CREATURE
|
||||
INVALID = -1,
|
||||
CREATURE_INFO,
|
||||
HERO_INFO,
|
||||
MOVE_TACTICS,
|
||||
CHOOSE_TACTICS_STACK,
|
||||
|
||||
MOVE_STACK,
|
||||
ATTACK,
|
||||
WALK_AND_ATTACK,
|
||||
ATTACK_AND_RETURN,
|
||||
SHOOT,
|
||||
CATAPULT,
|
||||
HEAL,
|
||||
|
||||
NO_LOCATION, // massive spells that affect every possible target, automatic casts
|
||||
ANY_LOCATION,
|
||||
OBSTACLE,
|
||||
TELEPORT,
|
||||
SACRIFICE,
|
||||
RANDOM_GENIE_SPELL, // random spell on a friendly creature
|
||||
FREE_LOCATION, // used with Force Field and Fire Wall - all tiles affected by spell must be free
|
||||
AIMED_SPELL_CREATURE, // spell targeted at creature
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE BattleClientInterfaceData
|
||||
|
@ -10,14 +10,12 @@
|
||||
#include "StdInc.h"
|
||||
#include "CBinaryReader.h"
|
||||
|
||||
//FIXME:library file depends on SDL - make cause troubles
|
||||
#include <SDL_endian.h>
|
||||
#include "CInputStream.h"
|
||||
#include "../CGeneralTextHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
#ifdef VCMI_ENDIAN_BIG
|
||||
template <typename CData>
|
||||
CData readLE(CData data)
|
||||
{
|
||||
|
@ -647,10 +647,7 @@ int64_t CGHeroInstance::getSpecificSpellBonus(const spells::Spell * spell, int64
|
||||
|
||||
int32_t CGHeroInstance::getEffectLevel(const spells::Spell * spell) const
|
||||
{
|
||||
if(hasBonusOfType(Bonus::MAXED_SPELL, spell->getIndex()))
|
||||
return 3;//todo: recheck specialty from where this bonus is. possible bug
|
||||
else
|
||||
return getSpellSchoolLevel(spell);
|
||||
return getSpellSchoolLevel(spell);
|
||||
}
|
||||
|
||||
int32_t CGHeroInstance::getEffectPower(const spells::Spell * spell) const
|
||||
|
@ -81,8 +81,8 @@ void CRandomRewardObjectInfo::configureLimiter(CRewardableObject * object, CRand
|
||||
|
||||
limiter.primary = JsonRandom::loadPrimary(source["primary"], rng);
|
||||
limiter.secondary = JsonRandom::loadSecondary(source["secondary"], rng);
|
||||
limiter.artifacts = JsonRandom::loadArtifacts(source["spells"], rng);
|
||||
limiter.spells = JsonRandom::loadSpells(source["artifacts"], rng, spells);
|
||||
limiter.artifacts = JsonRandom::loadArtifacts(source["artifacts"], rng);
|
||||
limiter.spells = JsonRandom::loadSpells(source["spells"], rng, spells);
|
||||
limiter.creatures = JsonRandom::loadCreatures(source["creatures"], rng);
|
||||
|
||||
limiter.allOf = configureSublimiters(object, rng, source["allOf"] );
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user