mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #1771 from IvanSavenko/beta_fixes
Fixes for issues discovered in beta
This commit is contained in:
commit
6a3f4fd73d
289
Mods/vcmi/config/vcmi/chinese.json
Normal file
289
Mods/vcmi/config/vcmi/chinese.json
Normal file
@ -0,0 +1,289 @@
|
||||
{
|
||||
"vcmi.adventureMap.monsterThreat.title" : "\n\n 威胁等级: ",
|
||||
"vcmi.adventureMap.monsterThreat.levels.0" : "极低",
|
||||
"vcmi.adventureMap.monsterThreat.levels.1" : "很低",
|
||||
"vcmi.adventureMap.monsterThreat.levels.2" : "低",
|
||||
"vcmi.adventureMap.monsterThreat.levels.3" : "较低",
|
||||
"vcmi.adventureMap.monsterThreat.levels.4" : "中等",
|
||||
"vcmi.adventureMap.monsterThreat.levels.5" : "较高",
|
||||
"vcmi.adventureMap.monsterThreat.levels.6" : "高",
|
||||
"vcmi.adventureMap.monsterThreat.levels.7" : "很高",
|
||||
"vcmi.adventureMap.monsterThreat.levels.8" : "挑战性的",
|
||||
"vcmi.adventureMap.monsterThreat.levels.9" : "压倒性的",
|
||||
"vcmi.adventureMap.monsterThreat.levels.10" : "致命的",
|
||||
"vcmi.adventureMap.monsterThreat.levels.11" : "无法取胜的",
|
||||
|
||||
"vcmi.adventureMap.confirmRestartGame" : "你想要重新开始游戏吗?",
|
||||
"vcmi.adventureMap.noTownWithMarket" : "没有足够的市场。",
|
||||
"vcmi.adventureMap.noTownWithTavern" : "没有酒馆可供查看。",
|
||||
"vcmi.adventureMap.spellUnknownProblem" : "无此魔法的信息。",
|
||||
"vcmi.adventureMap.playerAttacked" : "玩家遭受攻击: %s",
|
||||
"vcmi.adventureMap.moveCostDetails" : "移动点数 - 花费: %TURNS 轮 + %POINTS 点移动力, 剩余移动力: %REMAINING",
|
||||
"vcmi.adventureMap.moveCostDetailsNoTurns" : "移动点数 - 花费: %POINTS 点移动力, 剩余移动力: %REMAINING",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "另一个VCMI进程在运行,请结束当前进程。",
|
||||
"vcmi.server.errors.modsIncompatibility" : "需要加载mod:",
|
||||
"vcmi.server.confirmReconnect" : "连接到上次吗?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "常规",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "切换到“系统选项”选项卡 - 这些设置与常规游戏客户端行为相关",
|
||||
"vcmi.settingsMainWindow.battleTab.hover" : "战斗",
|
||||
"vcmi.settingsMainWindow.battleTab.help" : "切换到“战斗选项”选项卡 - 这些设置允许配置战斗界面和相关内容",
|
||||
"vcmi.settingsMainWindow.adventureTab.hover" : "冒险地图",
|
||||
"vcmi.settingsMainWindow.adventureTab.help" : "切换到“冒险地图”选项卡 - 冒险地图允许你移动英雄",
|
||||
"vcmi.settingsMainWindow.otherTab.hover" : "其他设置",
|
||||
"vcmi.settingsMainWindow.otherTab.help" : "切换到“其他设置”选项卡 - 由于各种原因,这些选项不适合其他类别",
|
||||
|
||||
"vcmi.systemOptions.fullscreenButton.hover" : "全屏",
|
||||
"vcmi.systemOptions.fullscreenButton.help" : "{全屏n}\n\n 当你选择全屏时,VCMI将会全屏运行,否则只会运行在指定框内",
|
||||
"vcmi.systemOptions.resolutionButton.hover" : "分辨率",
|
||||
"vcmi.systemOptions.resolutionButton.help" : "{选择分辨率}\n\n 改变游戏的分辨率,达到更加清晰的效果。需要重新启动才能完成更改。",
|
||||
"vcmi.systemOptions.resolutionMenu.hover" : "选择分辨率",
|
||||
"vcmi.systemOptions.resolutionMenu.help" : "选择游戏的分辨率。",
|
||||
"vcmi.systemOptions.fullscreenFailed" : "{全屏}\n\n 选择切换到全屏失败!当前分辨率不支持全屏!",
|
||||
"vcmi.systemOptions.framerateButton.hover" : "显示传输帧数",
|
||||
"vcmi.systemOptions.framerateButton.help" : "{显示传输帧数}\n\n 打开/关闭在游戏窗口角落的传输帧数计数器。",
|
||||
|
||||
"vcmi.adventureOptions.numericQuantities.hover" : "生物数量显示",
|
||||
"vcmi.adventureOptions.numericQuantities.help" : "{生物数量显示}\n\n 以数字 A-B 格式显示不准确的敌方生物数量。",
|
||||
"vcmi.adventureOptions.forceMovementInfo.hover" : "在状态栏中显示移动力",
|
||||
"vcmi.adventureOptions.forceMovementInfo.help" : "{在状态栏中显示移动力}\n\n 不需要按ALT就可以显示移动力。",
|
||||
"vcmi.adventureOptions.showGrid.hover" : "显示六角网格",
|
||||
"vcmi.adventureOptions.showGrid.help" : "{显示六角网格}\n\n 在战场上显示六角网格。",
|
||||
"vcmi.adventureOptions.mapScrollSpeed4.hover": "4",
|
||||
"vcmi.adventureOptions.mapScrollSpeed4.help": "设置动画速度为超快",
|
||||
"vcmi.adventureOptions.mapScrollSpeed5.hover": "5",
|
||||
"vcmi.adventureOptions.mapScrollSpeed5.help": "设置动画速度为极速",
|
||||
|
||||
"vcmi.battleOptions.showQueue.hover": "显示移动次序",
|
||||
"vcmi.battleOptions.showQueue.help": "{显示移动次序}\n\n 显示当前生物的移动次序。",
|
||||
"vcmi.battleOptions.queueSizeLabel.hover": "次序条尺寸 (设置后下一场战斗生效)",
|
||||
"vcmi.battleOptions.queueSizeAutoButton.hover": "自动设置尺寸",
|
||||
"vcmi.battleOptions.queueSizeAutoButton.help": "根据游戏分辨率设置尺寸 (像素小于700为小尺寸,根据实际调整)",
|
||||
"vcmi.battleOptions.queueSizeSmallButton.hover": "小尺寸",
|
||||
"vcmi.battleOptions.queueSizeSmallButton.help": "设置次序条为小尺寸",
|
||||
"vcmi.battleOptions.queueSizeBigButton.hover": "大尺寸",
|
||||
"vcmi.battleOptions.queueSizeBigButton.help": "设置次寻条为大尺寸(不能在像素小于700时生效)",
|
||||
"vcmi.battleOptions.animationsSpeed4.hover": "4",
|
||||
"vcmi.battleOptions.animationsSpeed4.help": "设置动画速度为超快",
|
||||
"vcmi.battleOptions.animationsSpeed5.hover": "5",
|
||||
"vcmi.battleOptions.animationsSpeed5.help": "设置动画速度为极速",
|
||||
"vcmi.battleOptions.animationsSpeed6.hover": "6",
|
||||
"vcmi.battleOptions.animationsSpeed6.help": "设置动画速度为最快",
|
||||
"vcmi.battleOptions.skipBattleIntroMusic.hover": "跳过开场音乐",
|
||||
"vcmi.battleOptions.skipBattleIntroMusic.help": "{跳过开场音乐}\n\n 战斗开始时跳过开场音乐,直接按Esc也可以跳过。",
|
||||
|
||||
"vcmi.otherOptions.availableCreaturesAsDwellingLabel.hover" : "显示所有可以招募的城镇生物",
|
||||
"vcmi.otherOptions.availableCreaturesAsDwellingLabel.help" : "{显示所有可以招募的城镇生物}\n\n 显示当前所有可供招募的城镇生物 (左下角)。",
|
||||
"vcmi.otherOptions.compactTownCreatureInfo.hover": "缩小城镇生物信息",
|
||||
"vcmi.otherOptions.compactTownCreatureInfo.help": "{缩小城镇生物信息}\n\n 将城镇生物信息最小化.",
|
||||
|
||||
"vcmi.townHall.missingBase" : "你必须先建造%s ",
|
||||
"vcmi.townHall.noCreaturesToRecruit" : "没有可供雇佣的生物。",
|
||||
"vcmi.townHall.greetingManaVortex" : "当你接近%s时,你的身体充满了新的能量。这使你的魔法值加倍。",
|
||||
"vcmi.townHall.greetingKnowledge" : "你学习了%s上的图形,并深入了解各种魔法的运作,这使你的知识点数+1。",
|
||||
"vcmi.townHall.greetingSpellPower" : "%s教你新的方法来集中你的魔法力量,这使你的力量点数+1。",
|
||||
"vcmi.townHall.greetingExperience" : "访问%s给你提供了更好的学习方法。这使你的经验值+1000。",
|
||||
"vcmi.townHall.greetingAttack" : "在%s参观后给你提供了更好的战斗技巧,这使你的攻击点数+1。",
|
||||
"vcmi.townHall.greetingDefence" : "在%s中度过一段时间后,经验丰富的勇士会教你额外的防御技能,这使你的防御点数+1。",
|
||||
"vcmi.townHall.hasNotProduced" : "本周%s并没有产生什么资源。",
|
||||
"vcmi.townHall.hasProduced" : "本周%s产生了%d个%s。",
|
||||
"vcmi.townHall.greetingCustomBonus" : "参观%s后,你的技巧有了提升。这使你受益匪浅。并且使你+%d %s%s",
|
||||
"vcmi.townHall.greetingCustomUntil" : "直到下一场战斗。",
|
||||
"vcmi.townHall.greetingInTownMagicWell" : "%s使你的魔法值恢复到最大值。",
|
||||
|
||||
"vcmi.logicalExpressions.anyOf" : "以下任何前提:",
|
||||
"vcmi.logicalExpressions.allOf" : "以下所有前提:",
|
||||
"vcmi.logicalExpressions.noneOf" : "无前提:",
|
||||
|
||||
"vcmi.heroWindow.openCommander.hover" : "开启指挥官界面",
|
||||
"vcmi.heroWindow.openCommander.help" : "开启英雄的指挥官界面",
|
||||
|
||||
"vcmi.commanderWindow.artifactMessage" : "你要把这个宝物还给英雄吗?",
|
||||
|
||||
"vcmi.creatureWindow.showBonuses.hover" : "属性界面",
|
||||
"vcmi.creatureWindow.showBonuses.help" : "显示指挥官的所有增强属性",
|
||||
"vcmi.creatureWindow.showSkills.hover" : "技能页面",
|
||||
"vcmi.creatureWindow.showSkills.help" : "显示指挥官的所有技能",
|
||||
"vcmi.creatureWindow.returnArtifact.hover" : "交换宝物",
|
||||
"vcmi.creatureWindow.returnArtifact.help" : "将宝物还到英雄的背包里",
|
||||
|
||||
"vcmi.questLog.hideComplete.hover" : "隐藏完成任务",
|
||||
"vcmi.questLog.hideComplete.help" : "隐藏所有完成的任务",
|
||||
|
||||
"vcmi.randomMapTab.widgets.defaultTemplate" : "默认",
|
||||
"vcmi.randomMapTab.widgets.templateLabel" : "格式",
|
||||
"vcmi.randomMapTab.widgets.teamAlignmentsButton" : "设置...",
|
||||
"vcmi.randomMapTab.widgets.teamAlignmentsLabel" : "同盟关系",
|
||||
|
||||
// few strings from WoG used by vcmi
|
||||
"vcmi.stackExperience.description" : "» 经 验 获 得 明 细 «\n\n生物类型 ................... : %s\n经验等级 ................. : %s (%i)\n经验点数 ............... : %i\n下一个等级所需经验 .. : %i\n每次战斗最大获得经验 ... : %i%% (%i)\n获得经验的生物数量 .... : %i\n最大招募数量\n不会丢失经验升级 .... : %i\n经验倍数 ........... : %.2f\n升级倍数 .............. : %.2f\n10级后经验值 ........ : %i\n最大招募数量下\n 升级到10级所需经验数量: %i",
|
||||
"vcmi.stackExperience.rank.1" : "新兵 1级",
|
||||
"vcmi.stackExperience.rank.2" : "列兵 2级",
|
||||
"vcmi.stackExperience.rank.3" : "下士 3级",
|
||||
"vcmi.stackExperience.rank.4" : "中士 4级",
|
||||
"vcmi.stackExperience.rank.5" : "上士 5级",
|
||||
"vcmi.stackExperience.rank.6" : "少尉 6级",
|
||||
"vcmi.stackExperience.rank.7" : "中尉 7级",
|
||||
"vcmi.stackExperience.rank.8" : "上尉 8级",
|
||||
"vcmi.stackExperience.rank.9" : "少校 9级",
|
||||
"vcmi.stackExperience.rank.10" : "中校 10级",
|
||||
"vcmi.stackExperience.rank.11" : "上校 11级",
|
||||
|
||||
"core.bonus.ADDITIONAL_ATTACK.name": "双击",
|
||||
"core.bonus.ADDITIONAL_ATTACK.description": "可以攻击两次",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.name": "额外反击",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.description": "可以额外反击 ${val} 次",
|
||||
"core.bonus.AIR_IMMUNITY.name": "气系免疫",
|
||||
"core.bonus.AIR_IMMUNITY.description": "免疫所有气系魔法",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.name": "环击",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.description": "攻击所有相邻部队",
|
||||
"core.bonus.BLOCKS_RETALIATION.name": "无反击",
|
||||
"core.bonus.BLOCKS_RETALIATION.description": "敌人无法反击",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.name": "远程无反击",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.description": "敌人无法对射击进行反击",
|
||||
"core.bonus.CATAPULT.name": "攻城",
|
||||
"core.bonus.CATAPULT.description": "可以攻击城墙",
|
||||
"core.bonus.CATAPULT_EXTRA_SHOTS.name": "额外攻击城墙",
|
||||
"core.bonus.CATAPULT_EXTRA_SHOTS.description": "可以额外攻击城墙 ${val} 次",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ALLY.name": "施法消耗 - (${val})",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ALLY.description": "减少英雄的施法消耗",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.name": "对方施法消耗 + (${val})",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.description": "增加对方施法消耗",
|
||||
"core.bonus.CHARGE_IMMUNITY.name": "I免疫冲锋",
|
||||
"core.bonus.CHARGE_IMMUNITY.description": "对冲锋特技的额外伤害免疫",
|
||||
"core.bonus.DARKNESS.name": "黑暗天幕",
|
||||
"core.bonus.DARKNESS.description": "增加 ${val} 半径黑幕",
|
||||
"core.bonus.DEATH_STARE.name": "死亡凝视 (${val}%)",
|
||||
"core.bonus.DEATH_STARE.description": "${val}% 几率直接杀死生物",
|
||||
"core.bonus.DEFENSIVE_STANCE.name": "防御奖励",
|
||||
"core.bonus.DEFENSIVE_STANCE.description": "当选择防御时+${val} 防御力",
|
||||
"core.bonus.DESTRUCTION.name": "毁灭",
|
||||
"core.bonus.DESTRUCTION.description": "有${val}% 杀死额外数量的部队",
|
||||
"core.bonus.DOUBLE_DAMAGE_CHANCE.name": "致命一击",
|
||||
"core.bonus.DOUBLE_DAMAGE_CHANCE.description": "${val}% 几率造成双倍伤害",
|
||||
"core.bonus.DRAGON_NATURE.name": "龙",
|
||||
"core.bonus.DRAGON_NATURE.description": "生物属于龙类",
|
||||
"core.bonus.DIRECT_DAMAGE_IMMUNITY.name": "魔法伤害免疫",
|
||||
"core.bonus.DIRECT_DAMAGE_IMMUNITY.description": "对魔法伤害免疫",
|
||||
"core.bonus.EARTH_IMMUNITY.name": "土系免疫",
|
||||
"core.bonus.EARTH_IMMUNITY.description": "免疫所有土系魔法",
|
||||
"core.bonus.ENCHANTER.name": "施法者",
|
||||
"core.bonus.ENCHANTER.description": "每回合群体施放 ${subtype.spell} ",
|
||||
"core.bonus.ENCHANTED.name": "魔法护身",
|
||||
"core.bonus.ENCHANTED.description": "自身被 ${subtype.spell} 魔法影响",
|
||||
"core.bonus.ENEMY_DEFENCE_REDUCTION.name": "忽略防御 (${val}%)",
|
||||
"core.bonus.ENEMY_DEFENCE_REDUCTION.description": "攻击时忽略对方部分防御力",
|
||||
"core.bonus.FIRE_IMMUNITY.name": "火系免疫",
|
||||
"core.bonus.FIRE_IMMUNITY.description": "免疫所有火系魔法",
|
||||
"core.bonus.FIRE_SHIELD.name": "烈火神盾 (${val}%)",
|
||||
"core.bonus.FIRE_SHIELD.description": "拥有烈火神盾护身",
|
||||
"core.bonus.FIRST_STRIKE.name": "抢先攻击",
|
||||
"core.bonus.FIRST_STRIKE.description": "在被反击前做出攻击",
|
||||
"core.bonus.FEAR.name": "恐惧",
|
||||
"core.bonus.FEAR.description": "引起恐惧",
|
||||
"core.bonus.FEARLESS.name": "无惧",
|
||||
"core.bonus.FEARLESS.description": "免疫恐惧",
|
||||
"core.bonus.FLYING.name": "飞行兵种",
|
||||
"core.bonus.FLYING.description": "生物可以飞行",
|
||||
"core.bonus.FREE_SHOOTING.name": "近身射击",
|
||||
"core.bonus.FREE_SHOOTING.description": "靠近敌方也能射击",
|
||||
"core.bonus.FULL_HP_REGENERATION.name": "重生",
|
||||
"core.bonus.FULL_HP_REGENERATION.description": "可以自动恢复所有生命值",
|
||||
"core.bonus.GARGOYLE.name": "石像鬼属性",
|
||||
"core.bonus.GARGOYLE.description": "不能被复活或治疗",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.name": "减少伤害 (${val}%)",
|
||||
"core.bonus.GENERAL_DAMAGE_REDUCTION.description": "受攻击时减少受到的伤害",
|
||||
"core.bonus.HATE.name": "${subtype.creature}的死敌",
|
||||
"core.bonus.HATE.description": "对该部队造成 ${val}% 的额外伤害",
|
||||
"core.bonus.HEALER.name": "治疗",
|
||||
"core.bonus.HEALER.description": "可以治疗友军单位",
|
||||
"core.bonus.HP_REGENERATION.name": "重生",
|
||||
"core.bonus.HP_REGENERATION.description": "每回合恢复 ${val} 点生命值",
|
||||
"core.bonus.JOUSTING.name": "冲锋",
|
||||
"core.bonus.JOUSTING.description": "每格行动增加+5%伤害",
|
||||
"core.bonus.KING1.name": "一般顶级怪物",
|
||||
"core.bonus.KING1.description": "被初级屠戮成性影响",
|
||||
"core.bonus.KING2.name": "智慧顶级怪物",
|
||||
"core.bonus.KING2.description": "被中级屠戮成性影响",
|
||||
"core.bonus.KING3.name": "精神顶级怪物",
|
||||
"core.bonus.KING3.description":"被高级屠戮成性影响",
|
||||
"core.bonus.LEVEL_SPELL_IMMUNITY.name": "免疫 1-${val} 级魔法",
|
||||
"core.bonus.LEVEL_SPELL_IMMUNITY.description": "免疫等级为 1-${val} 级的所有魔法",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.name" : "半程射击",
|
||||
"core.bonus.LIMITED_SHOOTING_RANGE.description" : "超过 ${val} 格不能射击",
|
||||
"core.bonus.LIFE_DRAIN.name": "吸取生命 (${val}%)",
|
||||
"core.bonus.LIFE_DRAIN.description": "吸取 ${val}% 伤害回复自身",
|
||||
"core.bonus.MANA_CHANNELING.name": "偷取魔法 ${val}%",
|
||||
"core.bonus.MANA_CHANNELING.description": "偷取部分敌人施法消耗",
|
||||
"core.bonus.MANA_DRAIN.name": "吸取魔力",
|
||||
"core.bonus.MANA_DRAIN.description": "每回合吸取 ${val} 魔法值",
|
||||
"core.bonus.MAGIC_MIRROR.name": "带有魔法神镜 (${val}%)",
|
||||
"core.bonus.MAGIC_MIRROR.description": "${val}% 几率反射魔法",
|
||||
"core.bonus.MAGIC_RESISTANCE.name": "(${MR}%) 魔法抵抗",
|
||||
"core.bonus.MAGIC_RESISTANCE.description": "${MR}% 几率抵抗敌人的魔法",
|
||||
"core.bonus.MIND_IMMUNITY.name": "免疫心智",
|
||||
"core.bonus.MIND_IMMUNITY.description": "不受心智魔法的影响",
|
||||
"core.bonus.NO_DISTANCE_PENALTY.name": "无障碍射击",
|
||||
"core.bonus.NO_DISTANCE_PENALTY.description": "射击不受距离影响",
|
||||
"core.bonus.NO_MELEE_PENALTY.name": "无近战惩罚",
|
||||
"core.bonus.NO_MELEE_PENALTY.description": "近战伤害不减",
|
||||
"core.bonus.NO_MORALE.name": "无士气",
|
||||
"core.bonus.NO_MORALE.description": "生物不受士气影响",
|
||||
"core.bonus.NO_WALL_PENALTY.name": "无城墙影响",
|
||||
"core.bonus.NO_WALL_PENALTY.description": "射击不受城墙的影响",
|
||||
"core.bonus.NON_LIVING.name": "无生命",
|
||||
"core.bonus.NON_LIVING.description": "不受只对生命实体生物有效的魔法",
|
||||
"core.bonus.RANDOM_SPELLCASTER.name": "随机施法",
|
||||
"core.bonus.RANDOM_SPELLCASTER.description": "随机施放增益魔法",
|
||||
"core.bonus.RANGED_RETALIATION.name": "远程反击",
|
||||
"core.bonus.RANGED_RETALIATION.description": "可以对远程攻击进行反击",
|
||||
"core.bonus.RECEPTIVE.name": "接受有益魔法",
|
||||
"core.bonus.RECEPTIVE.description": "不会免疫有益的魔法",
|
||||
"core.bonus.REBIRTH.name": "复生 (${val}%)",
|
||||
"core.bonus.REBIRTH.description": "{val}% 数量死亡后会复活",
|
||||
"core.bonus.RETURN_AFTER_STRIKE.name": "攻击并返回",
|
||||
"core.bonus.RETURN_AFTER_STRIKE.description": "攻击后回到初始位置",
|
||||
"core.bonus.SELF_LUCK.name": "永久幸运",
|
||||
"core.bonus.SELF_LUCK.description": "永久拥有幸运值",
|
||||
"core.bonus.SELF_MORALE.name": "士气高涨",
|
||||
"core.bonus.SELF_MORALE.description": "永久拥有高昂的士气",
|
||||
"core.bonus.SHOOTER.name": "射手",
|
||||
"core.bonus.SHOOTER.description": "生物可以设计",
|
||||
"core.bonus.SHOOTS_ALL_ADJACENT.name": "范围远程攻击",
|
||||
"core.bonus.SHOOTS_ALL_ADJACENT.description": "远程攻击可伤害范围内的多个目标",
|
||||
"core.bonus.SOUL_STEAL.name": "杀死敌人复生",
|
||||
"core.bonus.SOUL_STEAL.description": "当杀死敌人时获得 ${val} 数量",
|
||||
"core.bonus.SPELLCASTER.name": "施法者",
|
||||
"core.bonus.SPELLCASTER.description": "生物可以施放 ${subtype.spell}",
|
||||
"core.bonus.SPELL_AFTER_ATTACK.name": "攻击后施法",
|
||||
"core.bonus.SPELL_AFTER_ATTACK.description": "${val}% 攻击后施放 ${subtype.spell}",
|
||||
"core.bonus.SPELL_BEFORE_ATTACK.name": "攻击前施法",
|
||||
"core.bonus.SPELL_BEFORE_ATTACK.description": "${val}% 攻击前施放 ${subtype.spell}",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.name": "魔法伤害抵抗",
|
||||
"core.bonus.SPELL_DAMAGE_REDUCTION.description": "受魔法攻击时伤害减少 ${val}%",
|
||||
"core.bonus.SPELL_IMMUNITY.name": "特定魔法免疫",
|
||||
"core.bonus.SPELL_IMMUNITY.description": "免疫 ${subtype.spell}",
|
||||
"core.bonus.SPELL_LIKE_ATTACK.name": "魔法攻击",
|
||||
"core.bonus.SPELL_LIKE_ATTACK.description": "攻击时使用 ${subtype.spell}",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.name": "抗魔光环",
|
||||
"core.bonus.SPELL_RESISTANCE_AURA.description": "邻近部队获得 ${val}% 魔法抵抗",
|
||||
"core.bonus.SUMMON_GUARDIANS.name": "召唤守卫",
|
||||
"core.bonus.SUMMON_GUARDIANS.description": "战斗前召唤 ${subtype.creature} (${val}%)",
|
||||
"core.bonus.SYNERGY_TARGET.name": "可协助攻击",
|
||||
"core.bonus.SYNERGY_TARGET.description": "生物受到协助攻击的影响",
|
||||
"core.bonus.TWO_HEX_ATTACK_BREATH.name": "龙息",
|
||||
"core.bonus.TWO_HEX_ATTACK_BREATH.description": "吐息攻击2个部队",
|
||||
"core.bonus.THREE_HEADED_ATTACK.name": "半环击",
|
||||
"core.bonus.THREE_HEADED_ATTACK.description": "攻击正前方多个敌人",
|
||||
"core.bonus.TRANSMUTATION.name": "变换",
|
||||
"core.bonus.TRANSMUTATION.description": "${val}% 机会将敌人变成其他生物",
|
||||
"core.bonus.UNDEAD.name": "不死生物",
|
||||
"core.bonus.UNDEAD.description": "生物有丧尸属性",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.name": "无限反击",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.description": "每回合可以无限反击敌人",
|
||||
"core.bonus.WATER_IMMUNITY.name": "水系免疫",
|
||||
"core.bonus.WATER_IMMUNITY.description": "免疫水系魔法",
|
||||
"core.bonus.WIDE_BREATH.name": "弧形焰息",
|
||||
"core.bonus.WIDE_BREATH.description": "吐息攻击前方扇形6个部队"
|
||||
}
|
@ -1,6 +1,16 @@
|
||||
{
|
||||
"name" : "VCMI essential files",
|
||||
"description" : "Essential files required for VCMI to run correctly",
|
||||
|
||||
"chinese" : {
|
||||
"name" : "VCMI essential files",
|
||||
"description" : "Essential files required for VCMI to run correctly",
|
||||
|
||||
"skipValidation" : true,
|
||||
"translations" : [
|
||||
"config/vcmi/chinese.json"
|
||||
]
|
||||
},
|
||||
|
||||
"german" : {
|
||||
"name" : "VCMI - grundlegende Dateien",
|
||||
|
@ -131,7 +131,11 @@ std::vector<std::string> MapAudioPlayer::getAmbientSounds(const int3 & tile)
|
||||
{
|
||||
const auto & object = CGI->mh->getMap()->objects[objectID.getNum()];
|
||||
|
||||
if(object->getAmbientSound())
|
||||
assert(object);
|
||||
if (!object)
|
||||
logGlobal->warn("Already removed object %d found on tile! (%d %d %d)", objectID.getNum(), tile.x, tile.y, tile.z);
|
||||
|
||||
if(object && object->getAmbientSound())
|
||||
result.push_back(object->getAmbientSound().get());
|
||||
}
|
||||
|
||||
@ -194,8 +198,10 @@ MapAudioPlayer::MapAudioPlayer()
|
||||
objects.resize(boost::extents[mapSize.z][mapSize.x][mapSize.y]);
|
||||
|
||||
for(const auto & obj : CGI->mh->getMap()->objects)
|
||||
{
|
||||
if (obj)
|
||||
addObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
MapAudioPlayer::~MapAudioPlayer()
|
||||
|
@ -47,6 +47,10 @@ protected:
|
||||
void onAfterHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override;
|
||||
void onAfterHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override;
|
||||
|
||||
void onBeforeHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override {}
|
||||
void onBeforeHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override {}
|
||||
void onBeforeHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override {}
|
||||
|
||||
public:
|
||||
MapAudioPlayer();
|
||||
~MapAudioPlayer() override;
|
||||
|
@ -436,6 +436,9 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
||||
{
|
||||
BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(targetHex);
|
||||
DamageEstimation estimation = owner.curInt->cb->battleEstimateDamage(owner.stacksController->getActiveStack(), targetStack, attackFromHex);
|
||||
estimation.kills.max = std::min<int64_t>(estimation.kills.max, targetStack->getCount());
|
||||
estimation.kills.min = std::min<int64_t>(estimation.kills.min, targetStack->getCount());
|
||||
|
||||
return formatMeleeAttack(estimation, targetStack->getName());
|
||||
}
|
||||
|
||||
@ -444,6 +447,8 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
||||
const auto * shooter = owner.stacksController->getActiveStack();
|
||||
|
||||
DamageEstimation estimation = owner.curInt->cb->battleEstimateDamage(shooter, targetStack, shooter->getPosition());
|
||||
estimation.kills.max = std::min<int64_t>(estimation.kills.max, targetStack->getCount());
|
||||
estimation.kills.min = std::min<int64_t>(estimation.kills.min, targetStack->getCount());
|
||||
|
||||
return formatRangedAttack(estimation, targetStack->getName(), shooter->shots.available());
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
|
||||
, attackerInt(att)
|
||||
, defenderInt(defen)
|
||||
, curInt(att)
|
||||
, battleOpeningDelayActive(true)
|
||||
{
|
||||
if(spectatorInt)
|
||||
{
|
||||
@ -112,7 +113,7 @@ void BattleInterface::playIntroSoundAndUnlockInterface()
|
||||
}
|
||||
};
|
||||
|
||||
battleIntroSoundChannel = CCS->soundh->playSoundFromSet(CCS->soundh->battleIntroSounds);
|
||||
int battleIntroSoundChannel = CCS->soundh->playSoundFromSet(CCS->soundh->battleIntroSounds);
|
||||
if (battleIntroSoundChannel != -1)
|
||||
{
|
||||
CCS->soundh->setCallback(battleIntroSoundChannel, onIntroPlayed);
|
||||
@ -120,8 +121,15 @@ void BattleInterface::playIntroSoundAndUnlockInterface()
|
||||
if (settings["gameTweaks"]["skipBattleIntroMusic"].Bool())
|
||||
openingEnd();
|
||||
}
|
||||
else
|
||||
else // failed to play sound
|
||||
{
|
||||
onIntroSoundPlayed();
|
||||
}
|
||||
}
|
||||
|
||||
bool BattleInterface::openingPlaying()
|
||||
{
|
||||
return battleOpeningDelayActive;
|
||||
}
|
||||
|
||||
void BattleInterface::onIntroSoundPlayed()
|
||||
@ -132,6 +140,19 @@ void BattleInterface::onIntroSoundPlayed()
|
||||
CCS->musich->playMusicFromSet("battle", true, true);
|
||||
}
|
||||
|
||||
void BattleInterface::openingEnd()
|
||||
{
|
||||
assert(openingPlaying());
|
||||
if (!openingPlaying())
|
||||
return;
|
||||
|
||||
onAnimationsFinished();
|
||||
if(tacticsMode)
|
||||
tacticNextStack(nullptr);
|
||||
activateStack();
|
||||
battleOpeningDelayActive = false;
|
||||
}
|
||||
|
||||
BattleInterface::~BattleInterface()
|
||||
{
|
||||
CPlayerInterface::battleInt = nullptr;
|
||||
@ -530,24 +551,6 @@ void BattleInterface::activateStack()
|
||||
GH.fakeMouseMove();
|
||||
}
|
||||
|
||||
bool BattleInterface::openingPlaying()
|
||||
{
|
||||
return battleIntroSoundChannel != -1;
|
||||
}
|
||||
|
||||
void BattleInterface::openingEnd()
|
||||
{
|
||||
assert(openingPlaying());
|
||||
if (!openingPlaying())
|
||||
return;
|
||||
|
||||
onAnimationsFinished();
|
||||
if(tacticsMode)
|
||||
tacticNextStack(nullptr);
|
||||
activateStack();
|
||||
battleIntroSoundChannel = -1;
|
||||
}
|
||||
|
||||
bool BattleInterface::makingTurn() const
|
||||
{
|
||||
return stacksController->getActiveStack() != nullptr;
|
||||
|
@ -111,8 +111,8 @@ class BattleInterface
|
||||
/// defender interface, not null if attacker is human in our vcmiclient
|
||||
std::shared_ptr<CPlayerInterface> defenderInt;
|
||||
|
||||
/// ID of channel on which battle opening sound is playing, or -1 if none
|
||||
int battleIntroSoundChannel;
|
||||
/// if set to true, battle is still starting and waiting for intro sound to end / key press from player
|
||||
bool battleOpeningDelayActive;
|
||||
|
||||
void playIntroSoundAndUnlockInterface();
|
||||
void onIntroSoundPlayed();
|
||||
|
@ -88,16 +88,13 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
|
||||
static const auto shifterNegative = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 1.0f, 0.2f, 0.2f );
|
||||
static const auto shifterNeutral = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 1.0f, 1.0f, 0.2f );
|
||||
|
||||
amountNormal->adjustPalette(shifterNormal, 0);
|
||||
amountPositive->adjustPalette(shifterPositive, 0);
|
||||
amountNegative->adjustPalette(shifterNegative, 0);
|
||||
amountEffNeutral->adjustPalette(shifterNeutral, 0);
|
||||
// do not change border color
|
||||
static const int32_t ignoredMask = 1 << 26;
|
||||
|
||||
//Restore border color {255, 231, 132, 255} to its original state
|
||||
amountNormal->resetPalette(26);
|
||||
amountPositive->resetPalette(26);
|
||||
amountNegative->resetPalette(26);
|
||||
amountEffNeutral->resetPalette(26);
|
||||
amountNormal->adjustPalette(shifterNormal, ignoredMask);
|
||||
amountPositive->adjustPalette(shifterPositive, ignoredMask);
|
||||
amountNegative->adjustPalette(shifterNegative, ignoredMask);
|
||||
amountEffNeutral->adjustPalette(shifterNeutral, ignoredMask);
|
||||
|
||||
std::vector<const CStack*> stacks = owner.curInt->cb->battleGetAllStacks(true);
|
||||
for(const CStack * s : stacks)
|
||||
@ -187,7 +184,7 @@ void BattleStacksController::stackReset(const CStack * stack)
|
||||
void BattleStacksController::stackAdded(const CStack * stack, bool instant)
|
||||
{
|
||||
// Tower shooters have only their upper half visible
|
||||
static const int turretCreatureAnimationHeight = 225;
|
||||
static const int turretCreatureAnimationHeight = 232;
|
||||
|
||||
stackFacingRight[stack->ID] = stack->side == BattleSide::ATTACKER; // must be set before getting stack position
|
||||
|
||||
@ -201,6 +198,11 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant)
|
||||
|
||||
stackAnimation[stack->ID] = AnimationControls::getAnimation(turretCreature);
|
||||
stackAnimation[stack->ID]->pos.h = turretCreatureAnimationHeight;
|
||||
stackAnimation[stack->ID]->pos.w = stackAnimation[stack->ID]->getWidth();
|
||||
|
||||
// FIXME: workaround for visible animation of Medusa tails (animation disabled in H3)
|
||||
if (turretCreature->idNumber == CreatureID::MEDUSA )
|
||||
stackAnimation[stack->ID]->pos.w = 250;
|
||||
|
||||
coords = owner.siegeController->getTurretCreaturePosition(stack->initialPosition);
|
||||
}
|
||||
@ -209,10 +211,10 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant)
|
||||
stackAnimation[stack->ID] = AnimationControls::getAnimation(stack->getCreature());
|
||||
stackAnimation[stack->ID]->onAnimationReset += std::bind(&onAnimationFinished, stack, stackAnimation[stack->ID]);
|
||||
stackAnimation[stack->ID]->pos.h = stackAnimation[stack->ID]->getHeight();
|
||||
stackAnimation[stack->ID]->pos.w = stackAnimation[stack->ID]->getWidth();
|
||||
}
|
||||
stackAnimation[stack->ID]->pos.x = coords.x;
|
||||
stackAnimation[stack->ID]->pos.y = coords.y;
|
||||
stackAnimation[stack->ID]->pos.w = stackAnimation[stack->ID]->getWidth();
|
||||
stackAnimation[stack->ID]->setType(ECreatureAnimType::HOLDING);
|
||||
|
||||
if (!instant)
|
||||
|
@ -343,13 +343,14 @@ static SDL_Color addColors(const SDL_Color & base, const SDL_Color & over)
|
||||
|
||||
void CreatureAnimation::genSpecialPalette(IImage::SpecialPalette & target)
|
||||
{
|
||||
target[0] = genShadow(shadowAlpha / 2);
|
||||
target.resize(8);
|
||||
target[0] = genShadow(0);
|
||||
target[1] = genShadow(shadowAlpha / 2);
|
||||
target[2] = genShadow(shadowAlpha);
|
||||
target[3] = genShadow(shadowAlpha);
|
||||
target[4] = genBorderColor(getBorderStrength(elapsedTime), border);
|
||||
target[5] = addColors(genShadow(shadowAlpha), genBorderColor(getBorderStrength(elapsedTime), border));
|
||||
target[6] = addColors(genShadow(shadowAlpha / 2), genBorderColor(getBorderStrength(elapsedTime), border));
|
||||
// colors 2 & 3 are not used in creatures
|
||||
target[4] = genShadow(shadowAlpha);
|
||||
target[5] = genBorderColor(getBorderStrength(elapsedTime), border);
|
||||
target[6] = addColors(genShadow(shadowAlpha), genBorderColor(getBorderStrength(elapsedTime), border));
|
||||
target[7] = addColors(genShadow(shadowAlpha / 2), genBorderColor(getBorderStrength(elapsedTime), border));
|
||||
}
|
||||
|
||||
void CreatureAnimation::nextFrame(Canvas & canvas, const ColorFilter & shifter, bool facingRight)
|
||||
@ -371,8 +372,8 @@ void CreatureAnimation::nextFrame(Canvas & canvas, const ColorFilter & shifter,
|
||||
IImage::SpecialPalette SpecialPalette;
|
||||
genSpecialPalette(SpecialPalette);
|
||||
|
||||
image->setSpecialPallete(SpecialPalette);
|
||||
image->adjustPalette(shifter, 8);
|
||||
image->setSpecialPallete(SpecialPalette, IImage::SPECIAL_PALETTE_MASK_CREATURES);
|
||||
image->adjustPalette(shifter, IImage::SPECIAL_PALETTE_MASK_CREATURES);
|
||||
|
||||
canvas.draw(image, pos.topLeft(), Rect(0, 0, pos.w, pos.h));
|
||||
|
||||
|
@ -26,27 +26,27 @@ public:
|
||||
virtual bool hasOngoingAnimations() = 0;
|
||||
|
||||
/// Plays fade-in animation and adds object to map
|
||||
virtual void onObjectFadeIn(const CGObjectInstance * obj) {}
|
||||
virtual void onObjectFadeIn(const CGObjectInstance * obj) = 0;
|
||||
|
||||
/// Plays fade-out animation and removed object from map
|
||||
virtual void onObjectFadeOut(const CGObjectInstance * obj) {}
|
||||
virtual void onObjectFadeOut(const CGObjectInstance * obj) = 0;
|
||||
|
||||
/// Adds object to map instantly, with no animation
|
||||
virtual void onObjectInstantAdd(const CGObjectInstance * obj) {}
|
||||
virtual void onObjectInstantAdd(const CGObjectInstance * obj) = 0;
|
||||
|
||||
/// Removes object from map instantly, with no animation
|
||||
virtual void onObjectInstantRemove(const CGObjectInstance * obj) {}
|
||||
virtual void onObjectInstantRemove(const CGObjectInstance * obj) = 0;
|
||||
|
||||
/// Perform hero movement animation, moving hero across terrain
|
||||
virtual void onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
||||
virtual void onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest) = 0;
|
||||
|
||||
/// Perform initialization of hero teleportation animation with terrain fade animation
|
||||
virtual void onBeforeHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
||||
virtual void onAfterHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
|
||||
virtual void onBeforeHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) = 0;
|
||||
virtual void onAfterHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) = 0;
|
||||
|
||||
virtual void onBeforeHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest){};
|
||||
virtual void onAfterHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest){};
|
||||
virtual void onBeforeHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) = 0;
|
||||
virtual void onAfterHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) = 0;
|
||||
|
||||
virtual void onBeforeHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest){};
|
||||
virtual void onAfterHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest){};
|
||||
virtual void onBeforeHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) = 0;
|
||||
virtual void onAfterHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest) = 0;
|
||||
};
|
||||
|
@ -40,7 +40,8 @@ enum class EImageBlitMode : uint8_t
|
||||
class IImage
|
||||
{
|
||||
public:
|
||||
using SpecialPalette = std::array<SDL_Color, 7>;
|
||||
using SpecialPalette = std::vector<SDL_Color>;
|
||||
static constexpr int32_t SPECIAL_PALETTE_MASK_CREATURES = 0b11110011;
|
||||
|
||||
//draws image on surface "where" at position
|
||||
virtual void draw(SDL_Surface * where, int posX = 0, int posY = 0, const Rect * src = nullptr) const = 0;
|
||||
@ -65,7 +66,7 @@ public:
|
||||
|
||||
//only indexed bitmaps, 16 colors maximum
|
||||
virtual void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) = 0;
|
||||
virtual void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) = 0;
|
||||
virtual void adjustPalette(const ColorFilter & shifter, uint32_t colorsToSkipMask) = 0;
|
||||
virtual void resetPalette(int colorID) = 0;
|
||||
virtual void resetPalette() = 0;
|
||||
|
||||
@ -73,7 +74,7 @@ public:
|
||||
virtual void setBlitMode(EImageBlitMode mode) = 0;
|
||||
|
||||
//only indexed bitmaps with 7 special colors
|
||||
virtual void setSpecialPallete(const SpecialPalette & SpecialPalette) = 0;
|
||||
virtual void setSpecialPallete(const SpecialPalette & SpecialPalette, uint32_t colorsToSkipMask) = 0;
|
||||
|
||||
virtual void horizontalFlip() = 0;
|
||||
virtual void verticalFlip() = 0;
|
||||
|
@ -308,7 +308,7 @@ void SDLImage::shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32
|
||||
}
|
||||
}
|
||||
|
||||
void SDLImage::adjustPalette(const ColorFilter & shifter, size_t colorsToSkip)
|
||||
void SDLImage::adjustPalette(const ColorFilter & shifter, uint32_t colorsToSkipMask)
|
||||
{
|
||||
if(originalPalette == nullptr)
|
||||
return;
|
||||
@ -316,8 +316,11 @@ void SDLImage::adjustPalette(const ColorFilter & shifter, size_t colorsToSkip)
|
||||
SDL_Palette* palette = surf->format->palette;
|
||||
|
||||
// Note: here we skip first colors in the palette that are predefined in H3 images
|
||||
for(int i = colorsToSkip; i < palette->ncolors; i++)
|
||||
for(int i = 0; i < palette->ncolors; i++)
|
||||
{
|
||||
if(i < std::numeric_limits<uint32_t>::digits && ((colorsToSkipMask >> i) & 1) == 1)
|
||||
continue;
|
||||
|
||||
palette->colors[i] = shifter.shiftColor(originalPalette->colors[i]);
|
||||
}
|
||||
}
|
||||
@ -340,11 +343,17 @@ void SDLImage::resetPalette( int colorID )
|
||||
SDL_SetPaletteColors(surf->format->palette, originalPalette->colors + colorID, colorID, 1);
|
||||
}
|
||||
|
||||
void SDLImage::setSpecialPallete(const IImage::SpecialPalette & SpecialPalette)
|
||||
void SDLImage::setSpecialPallete(const IImage::SpecialPalette & specialPalette, uint32_t colorsToSkipMask)
|
||||
{
|
||||
if(surf->format->palette)
|
||||
{
|
||||
CSDL_Ext::setColors(surf, const_cast<SDL_Color *>(SpecialPalette.data()), 1, 7);
|
||||
size_t last = std::min<size_t>(specialPalette.size(), surf->format->palette->ncolors);
|
||||
|
||||
for (size_t i = 0; i < last; ++i)
|
||||
{
|
||||
if(i < std::numeric_limits<uint32_t>::digits && ((colorsToSkipMask >> i) & 1) == 1)
|
||||
surf->format->palette->colors[i] = specialPalette[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,14 +66,14 @@ public:
|
||||
void verticalFlip() override;
|
||||
|
||||
void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) override;
|
||||
void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) override;
|
||||
void adjustPalette(const ColorFilter & shifter, uint32_t colorsToSkipMask) override;
|
||||
void resetPalette(int colorID) override;
|
||||
void resetPalette() override;
|
||||
|
||||
void setAlpha(uint8_t value) override;
|
||||
void setBlitMode(EImageBlitMode mode) override;
|
||||
|
||||
void setSpecialPallete(const SpecialPalette & SpecialPalette) override;
|
||||
void setSpecialPallete(const SpecialPalette & SpecialPalette, uint32_t colorsToSkipMask) override;
|
||||
|
||||
friend class SDLImageLoader;
|
||||
|
||||
|
@ -1210,7 +1210,8 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
|
||||
|
||||
CCastleInterface::~CCastleInterface()
|
||||
{
|
||||
adventureInt->onAudioResumed();
|
||||
if (adventureInt) // may happen on exiting client with open castle interface
|
||||
adventureInt->onAudioResumed();
|
||||
if(LOCPLINT->castleInt == this)
|
||||
LOCPLINT->castleInt = nullptr;
|
||||
}
|
||||
|
@ -924,6 +924,9 @@ void CMarketplaceWindow::artifactsChanged(bool Left)
|
||||
toRemove.insert(item);
|
||||
|
||||
removeItems(toRemove);
|
||||
|
||||
// clear set to erase final instance of shared_ptr - we want to redraw screen only after it has been deleted
|
||||
toRemove.clear();
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,7 @@ std::shared_ptr<CPicture> CWindowObject::createBg(std::string imageName, bool pl
|
||||
return nullptr;
|
||||
|
||||
auto image = std::make_shared<CPicture>(imageName);
|
||||
image->getSurface()->setBlitMode(EImageBlitMode::OPAQUE);
|
||||
if(playerColored)
|
||||
image->colorize(LOCPLINT->playerID);
|
||||
return image;
|
||||
|
@ -68,7 +68,7 @@
|
||||
"alpha" : 0.0
|
||||
},
|
||||
{
|
||||
"time" : 0.2
|
||||
"time" : 0.5
|
||||
},
|
||||
],
|
||||
"teleportFadeOut" : [
|
||||
@ -76,7 +76,7 @@
|
||||
"time" : 0.0
|
||||
},
|
||||
{
|
||||
"time" : 0.2,
|
||||
"time" : 0.5,
|
||||
"alpha" : 0.0
|
||||
},
|
||||
],
|
||||
|
@ -64,12 +64,12 @@
|
||||
},
|
||||
"language" : {
|
||||
"type":"string",
|
||||
"enum" : [ "chinese", "english", "german", "polish", "russian", "spanish", "ukrainian" ],
|
||||
"enum" : [ "english", "chinese", "german", "polish", "russian", "spanish", "ukrainian" ],
|
||||
"default" : "english"
|
||||
},
|
||||
"gameDataLanguage" : {
|
||||
"type":"string",
|
||||
"enum" : [ "auto", "chinese", "english", "german", "korean", "polish", "russian", "spanish", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
|
||||
"enum" : [ "auto", "english", "chinese", "german", "korean", "polish", "russian", "spanish", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
|
||||
"default" : "auto"
|
||||
},
|
||||
"lastSave" : {
|
||||
|
@ -684,7 +684,7 @@ void CModInfo::loadLocalData(const JsonNode & data)
|
||||
{
|
||||
bool validated = false;
|
||||
implicitlyEnabled = true;
|
||||
explicitlyEnabled = true;
|
||||
explicitlyEnabled = !config["keepDisabled"].Bool();
|
||||
checksum = 0;
|
||||
if (data.getType() == JsonNode::JsonType::DATA_BOOL)
|
||||
{
|
||||
|
@ -1120,6 +1120,7 @@ public:
|
||||
LICHES = 64,
|
||||
BONE_DRAGON = 68,
|
||||
TROGLODYTES = 70,
|
||||
MEDUSA = 76,
|
||||
HYDRA = 110,
|
||||
CHAOS_HYDRA = 111,
|
||||
AIR_ELEMENTAL = 112,
|
||||
@ -1245,7 +1246,7 @@ class ObstacleInfo;
|
||||
class Obstacle : public BaseForID<Obstacle, si32>
|
||||
{
|
||||
INSTID_LIKE_CLASS_COMMON(Obstacle, si32)
|
||||
|
||||
|
||||
DLL_LINKAGE const ObstacleInfo * getInfo() const;
|
||||
DLL_LINKAGE operator std::string() const;
|
||||
DLL_LINKAGE static Obstacle fromString(const std::string & identifier);
|
||||
|
@ -1004,12 +1004,19 @@ std::set<BattleHex> CBattleInfoCallback::getStoppers(BattlePerspective::BattlePe
|
||||
|
||||
for(auto &oi : battleGetAllObstacles(whichSidePerspective))
|
||||
{
|
||||
if(battleIsObstacleVisibleForSide(*oi, whichSidePerspective))
|
||||
if(!battleIsObstacleVisibleForSide(*oi, whichSidePerspective))
|
||||
continue;
|
||||
|
||||
for(const auto & hex : oi->getStoppingTile())
|
||||
{
|
||||
range::copy(oi->getStoppingTile(), vstd::set_inserter(ret));
|
||||
if(hex == ESiegeHex::GATE_BRIDGE && oi->obstacleType == CObstacleInstance::MOAT)
|
||||
{
|
||||
if(battleGetGateState() == EGateState::OPENED || battleGetGateState() == EGateState::DESTROYED)
|
||||
continue; // this tile is disabled by drawbridge on top of it
|
||||
}
|
||||
ret.insert(hex);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user