1-- _________ __ __ 2-- / _____// |_____________ _/ |______ ____ __ __ ______ 3-- \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/ 4-- / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ \ 5-- /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ > 6-- \/ \/ \//_____/ \/ 7-- ______________________ ______________________ 8-- T H E W A R B E G I N S 9-- Stratagus - A free fantasy real time strategy game engine 10-- 11-- (c) Copyright 2014-2019 by Andrettin 12-- 13-- This program is free software; you can redistribute it and/or modify 14-- it under the terms of the GNU General Public License as published by 15-- the Free Software Foundation; either version 2 of the License, or 16-- (at your option) any later version. 17-- 18-- This program is distributed in the hope that it will be useful, 19-- but WITHOUT ANY WARRANTY; without even the implied warranty of 20-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21-- GNU General Public License for more details. 22-- 23-- You should have received a copy of the GNU General Public License 24-- along with this program; if not, write to the Free Software 25-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26-- 27 28RunningScenario = false 29QuestWorlds = {"~!Earth", "~!Nidavellir"} 30 31function RunQuestWorldMenu() 32 SetPlayerData(GetThisPlayer(), "RaceName", "gnome") 33 34 if not (IsMusicPlaying()) then 35 PlayMusicName("MenuTheme") 36 end 37 38 local menu = WarMenu() 39 local offx = (Video.Width - 640) / 2 40 local offy = (Video.Height - 480) / 2 41 42 menu:addLabel(_("~<Quests~>"), offx + 320, offy + 212 - 25 - (36 * 1)) 43 44 local quest_world_y = 2 45 for i=1, table.getn(QuestWorlds) do 46 local quest_world_hotkey = "" 47 if (string.find(QuestWorlds[i], "~!") ~= nil) then 48 quest_world_hotkey = string.sub(string.match(_(QuestWorlds[i]), "~!%a"), 3) 49 quest_world_hotkey = string.lower(quest_world_hotkey) 50 end 51 local quest_world_name = string.gsub(QuestWorlds[i], "~!", "") 52 quest_world_name = string.lower(quest_world_name) 53 54 menu:addFullButton(_(QuestWorlds[i]), quest_world_hotkey, offx + 208, offy + 104 + 36*quest_world_y, 55 function() 56 RunQuestMenu(quest_world_name); 57 if (RunningScenario) then 58 menu:stop() 59 end 60 end) 61 62 quest_world_y = quest_world_y + 1 63 end 64 65 menu:addFullButton(_("~!Previous Menu"), "p", offx + 208, offy + 104 + 36*quest_world_y, 66 function() menu:stop() end 67 ) 68 return menu:run() 69end 70 71function RunQuestMenu(world) 72 SetPlayerData(GetThisPlayer(), "RaceName", "gnome") 73 74 if not (IsMusicPlaying()) then 75 PlayMusicName("MenuTheme") 76 end 77 78 local no_randomness 79 local no_time_of_day 80 local menu = WarMenu() 81 local offx = (Video.Width - 640) / 2 82 local offy = (Video.Height - 480) / 2 83 84 RunningScenario = false 85 86 menu:addLabel(_("~<Quests~>"), offx + 320, offy + 104 + 36*-2) 87 88 local completed_quest_quantity = 0 89 local total_quest_quantity = 0 90 local item_x = 1 91 local item_y = 1 92 local quests = GetQuests() 93 for i=1, table.getn(quests) do 94 if (GetQuestData(quests[i], "Hidden") == false and GetQuestData(quests[i], "World") == world and GetQuestData(quests[i], "Map") ~= "") then 95 total_quest_quantity = total_quest_quantity + 1 96 if (GetQuestData(quests[i], "RequiredQuest") == "" or GetQuestData(GetQuestData(quests[i], "RequiredQuest"), "Completed") or GetQuestData(quests[i], "Completed")) then 97 addQuestIcon(quests[i], menu, offx + 23 + 4 + (54 * item_x), offy + 10 + 4 + (46 * (item_y + 1))) -- increase Y by 1 because there are few enough quests that it makes sense to make the existing quests more centralized in the interface 98 99 item_x = item_x + 1 100 if (item_x > 9) then 101 item_x = 1 102 item_y = item_y + 1 103 end 104 if (GetQuestData(quests[i], "Completed")) then 105 completed_quest_quantity = completed_quest_quantity + 1 106 end 107 end 108 end 109 end 110 111 --[[ 112 local quest_completion_percent = completed_quest_quantity * 100 / total_quest_quantity 113 local badge_icon 114 if (quest_completion_percent == 100) then 115 badge_icon = CGraphic:New("ui/icons/badge_foil.png") 116 elseif (quest_completion_percent >= 80) then 117 badge_icon = CGraphic:New("ui/icons/badge_gold.png") 118 elseif (quest_completion_percent >= 60) then 119 badge_icon = CGraphic:New("ui/icons/badge_silver.png") 120 elseif (quest_completion_percent >= 40) then 121 badge_icon = CGraphic:New("ui/icons/badge_bronze.png") 122 elseif (quest_completion_percent >= 20) then 123 badge_icon = CGraphic:New("ui/icons/badge_glow.png") 124 else 125 badge_icon = CGraphic:New("ui/icons/badge_cracked.png") 126 end 127 badge_icon:Load() 128 local b = ImageWidget(badge_icon) 129 menu:add(b, (Video.Width / 2) - (badge_icon:getWidth() / 2), (Video.Height / 2) - (badge_icon:getHeight() / 2)) 130 b:setTooltip(completed_quest_quantity .. "/" .. total_quest_quantity .. " Quests Completed") 131 --]] 132 menu:addLabel(completed_quest_quantity .. "/" .. total_quest_quantity .. _(" Quests Completed"), Video.Width / 2, Video.Height / 2, Fonts["game"], true) 133 134 no_randomness = menu:addImageCheckBox(_("No Randomness"), offx + 480, offy + 10 + 270 + 3, 135 function() 136 wyr.preferences.NoRandomness = no_randomness:isMarked() 137 SavePreferences() 138 end 139 ) 140 no_randomness:setMarked(wyr.preferences.NoRandomness) 141 142 no_time_of_day = menu:addImageCheckBox(_("No Day/Night Cycle"), offx + 480, offy + 10 + 300 + 3, 143 function() 144 wyr.preferences.NoTimeOfDay = no_time_of_day:isMarked() 145 SavePreferences() 146 end 147 ) 148 no_time_of_day:setMarked(wyr.preferences.NoTimeOfDay) 149 150 local difficulty_list = {_("Easy"), _("Normal"), _("Hard"),_("Brutal")} 151 local difficulty = nil 152 153 menu:addLabel(_("Difficulty:"), offx + 244, offy + (10 + 300) - 20, Fonts["game"], false) 154 difficulty = menu:addDropDown(difficulty_list, offx + 244, offy + 10 + 300, 155 function(dd) 156 wyr.preferences.Difficulty = difficulty:getSelected() + 1 157 SavePreferences() 158 end 159 ) 160 difficulty:setSize(152, 20) 161 difficulty:setSelected(wyr.preferences.Difficulty - 1) 162 163 local custom_heroes = GetCustomHeroes() 164 local hero_list = {} 165 local hero_name_list = {} 166 for i=1,table.getn(custom_heroes) do 167 if ( 168 (world == "earth" and (GetCustomHeroData(custom_heroes[i], "Civilization") == "germanic" or GetCustomHeroData(custom_heroes[i], "Civilization") == "anglo-saxon" or GetCustomHeroData(custom_heroes[i], "Civilization") == "english" or GetCustomHeroData(custom_heroes[i], "Civilization") == "frankish" or GetCustomHeroData(custom_heroes[i], "Civilization") == "goth" or GetCustomHeroData(custom_heroes[i], "Civilization") == "suebi" or GetCustomHeroData(custom_heroes[i], "Civilization") == "teuton" or GetCustomHeroData(custom_heroes[i], "Civilization") == "norse" or GetCustomHeroData(custom_heroes[i], "Civilization") == "latin")) 169 or (world == "nidavellir" and GetCustomHeroData(custom_heroes[i], "Civilization") == "dwarf") 170 or (world == "nidavellir" and GetCustomHeroData(custom_heroes[i], "Civilization") == "gnome") 171 or (world == "nidavellir" and GetCustomHeroData(custom_heroes[i], "Civilization") == "goblin") 172 ) then 173 table.insert(hero_list, custom_heroes[i]) 174 end 175 end 176 local hero_dd 177 table.sort(hero_list) 178 for i=1,table.getn(hero_list) do 179 table.insert(hero_name_list, GetCustomHeroData(hero_list[i], "FullName")) 180 end 181 table.insert(hero_list, "") -- to allow players to choose having no custom hero selected 182 table.insert(hero_name_list, "") 183 menu:addLabel(_("Custom Hero:"), offx + 30, offy + (10 + 300) - 20, Fonts["game"], false) 184 hero_dd = menu:addDropDown(hero_name_list, offx + 30, offy + 10 + 300, 185 function(dd) 186 SetCurrentCustomHero(hero_list[hero_dd:getSelected() + 1]) 187 menu:stop() 188 RunQuestMenu(world) 189 end 190 ) 191 hero_dd:setSize(152, 20) 192 hero_dd:setSelected(GetElementIndexFromArray(hero_list, GetCurrentCustomHero()) - 1) 193 194 menu:addFullButton(_("Create Custom ~!Hero"), "h", offx + 208, offy + 212 + (36 * 4), 195 function() CustomHeroCreationMenu(world, menu); 196 end 197 ) 198 199 menu:addFullButton(_("~!Delete Custom Hero"), "d", offx + 208 + 226, offy + 212 + (36 * 4), 200 function() 201 if (GetCurrentCustomHero() ~= "") then 202 local confirm = WarGameMenu(panel(4)) 203 204 confirm:resize(288,128) 205 206 confirm:addLabel(_("Delete ") .. GetCurrentCustomHero(), 288 / 2, 11) 207 confirm:addLabel(_("Are you sure?") .. " This cannot be undone.", 288 / 2, 45, Fonts["game"]) 208 209 confirm:addHalfButton(_("~!Yes"), "y", 1 * (288 / 3) - 90, 120 - 16 - 27, 210 function() 211 DeleteCustomHero(GetCurrentCustomHero()) 212 confirm:stop() 213 menu:stop(); RunQuestMenu(world); 214 end 215 ) 216 217 confirm:addHalfButton(_("~!No"), "n", 3 * (288 / 3) - 116, 120 - 16 - 27, 218 function() confirm:stop() end 219 ) 220 221 confirm:run() 222 end 223 end 224 ) 225 226 menu:addFullButton(_("~!Previous Menu"), "p", offx + 208, offy + 212 + (36 * 5), 227 function() 228 SetCurrentCustomHero("") 229 menu:stop(); 230 end 231 ) 232 233 menu:run() 234end 235 236function addQuestIcon(quest, menu, x, y) 237 local quest_icon_frame = CIcon:Get(GetQuestData(quest, "Icon")).Frame 238 local questicon 239 local b 240 if (GetQuestData(quest, "Completed")) then 241 questicon = CIcon:Get(GetQuestData(quest, "Icon")).GScale 242 else 243 questicon = CIcon:Get(GetQuestData(quest, "Icon")).G 244 end 245 b = PlayerColorImageButton("", GetQuestData(quest, "PlayerColor")) 246 local quest_icon_x_origin = (quest_icon_frame * 46) % questicon:getGraphicWidth() 247 local quest_icon_y_origin = math.floor((quest_icon_frame * 46) / questicon:getGraphicWidth()) * 38 248 b:setActionCallback( 249 function() 250 PlaySound("click") 251 252 local quest_menu = WarGameMenu(panel(5)) 253 quest_menu:setSize(352, 352) 254 quest_menu:setPosition((Video.Width - quest_menu:getWidth()) / 2, (Video.Height - quest_menu:getHeight()) / 2) 255 quest_menu:addLabel(_(GetQuestData(quest, "Name")), 176, 11) 256 local quest_menu_image = PlayerColorImageWidget(questicon, GetQuestData(quest, "PlayerColor")) 257 quest_menu_image:setImageOrigin(quest_icon_x_origin, quest_icon_y_origin) 258 quest_menu:add(quest_menu_image, 153, 48) 259 260 local l = MultiLineLabel() 261 l:setFont(Fonts["game"]) 262 l:setSize(324, 208) 263 l:setLineWidth(324) 264 quest_menu:add(l, 14, 112) 265 local quest_description = _(GetQuestData(quest, "Description")) 266 l:setCaption(quest_description) 267 268 if (GetQuestData(quest, "Map") ~= "") then 269 quest_menu:addFullButton(_("~!Play Quest"), "p", 176 - (224 / 2), 352 - 40 * 2, 270 function() 271 RunningScenario = true 272 SetCurrentQuest(quest) 273 GetMapInfo(GetQuestData(quest, "Map")) 274 for i=1,mapinfo.nplayers do 275 if ((i - 1) ~= MapPersonPlayer and mapinfo.playertypes[i] == "person") then 276 GameSettings.Presets[i-1].Type = PlayerComputer 277 end 278 end 279 GameSettings.NoRandomness = wyr.preferences.NoRandomness 280 GameSettings.NoTimeOfDay = wyr.preferences.NoTimeOfDay 281 GameSettings.Difficulty = wyr.preferences.Difficulty 282 if (GetQuestData(quest, "Briefing") ~= "") then 283 Briefing(quest) 284 end 285 mapname = GetQuestData(quest, "Map") 286 quest_menu:stop() 287 RunMap(mapname) 288 menu:stop() 289 if not (LoadGameFile) then 290 RunQuestMenu(GetQuestData(quest, "World")) 291 end 292 end 293 ) 294 end 295 quest_menu:addFullButton(_("~!Close"), "c", 176 - (224 / 2), 352 - 40 * 1, 296 function() 297 quest_menu:stop() 298 end 299 ) 300 quest_menu:run() 301 end 302 ) 303 menu:add(b, x, y) 304 b:setImageOrigin(quest_icon_x_origin, quest_icon_y_origin) 305 b:setNormalImage(questicon) 306 b:setPressedImage(questicon) 307 b:setDisabledImage(questicon) 308 b:setSize(46, 38) 309 b:setBorderSize(0) -- Andrettin: make buttons not have the borders they previously had 310 b:setFrameImage(Preference.IconFrameG) 311 b:setPressedFrameImage(Preference.PressedIconFrameG) 312 local tooltip = _(GetQuestData(quest, "Name")) .. " (" .. GetCivilizationData(GetQuestData(quest, "Civilization"), "Display") .. ")" 313 if (GetQuestData(quest, "HighestCompletedDifficulty") >= DifficultyEasy) then 314 tooltip = tooltip .. "\nHighest Completed Difficulty: " 315 if (GetQuestData(quest, "HighestCompletedDifficulty") == DifficultyEasy) then 316 tooltip = tooltip .. _("Easy") 317 elseif (GetQuestData(quest, "HighestCompletedDifficulty") == DifficultyNormal) then 318 tooltip = tooltip .. _("Normal") 319 elseif (GetQuestData(quest, "HighestCompletedDifficulty") == DifficultyHard) then 320 tooltip = tooltip .. _("Hard") 321 elseif (GetQuestData(quest, "HighestCompletedDifficulty") == DifficultyBrutal) then 322 tooltip = tooltip .. _("Brutal") 323 end 324 end 325 b:setTooltip(tooltip) 326 return b 327end 328 329function Briefing(quest) 330 if (GetQuestData(quest, "Civilization") ~= "") then 331 SetPlayerData(GetThisPlayer(), "RaceName", GetQuestData(quest, "Civilization")) 332 end 333 334 local briefing_background = GetBackground("ui/backgrounds/wyrm.png") 335 if (GetQuestData(quest, "BriefingBackground") ~= "") then 336 briefing_background = GetBackground(GetQuestData(quest, "BriefingBackground")) 337 end 338 339 local menu = WarMenu(nil, briefing_background) 340 341 if (GetQuestData(quest, "BriefingMusic") ~= "") then 342 PlayMusic(GetQuestData(quest, "BriefingMusic")) 343 else 344 StopMusic() 345 end 346 347 menu:addLabel(quest, Video.Width / 2, 28 * Video.Height / 480, Fonts["large"], true) 348 349 local t = GetQuestData(quest, "Briefing") 350 t = "\n\n\n\n\n\n\n\n\n\n" .. t .. "\n\n\n\n\n\n\n\n\n\n\n\n\n" 351 local sw = ScrollingWidget(320, 170 * Video.Height / 480) 352 sw:setBackgroundColor(Color(0,0,0,0)) 353 sw:setSpeed(0.28) 354 local l = MultiLineLabel(t) 355 l:setFont(Fonts["large"]) 356 l:setAlignment(MultiLineLabel.LEFT) 357 l:setVerticalAlignment(MultiLineLabel.TOP) 358 l:setLineWidth(320) 359 l:adjustSize() 360 sw:add(l, 0, 0) 361 menu:add(sw, Video.Width / 2 - (l:getWidth() / 2), 80 * Video.Height / 480) 362 363 if (table.getn(GetQuestData(quest, "Objectives")) > 0) then 364 menu:addLabel(_("Objectives:"), 372 * Video.Width / 640, 306 * Video.Height / 480, Fonts["large"], false) 365 366 local objectives = "" 367 table.foreachi(GetQuestData(quest, "Objectives"), function(k,v) objectives = objectives .. v .. "\n" end) 368 369 local l = MultiLineLabel(objectives) 370 l:setFont(Fonts["large"]) 371 l:setAlignment(MultiLineLabel.LEFT) 372 l:setLineWidth(250 * Video.Width / 640) 373 l:adjustSize() 374 menu:add(l, 372 * Video.Width / 640, (306 * Video.Height / 480) + 30) 375 end 376 377 local voice = 0 378 local channel = -1 379 380 menu:addFullButton(_("~!Continue"), "c", Video.Width / 2 - 112, 440 * Video.Height / 480, 381 function() 382 if (table.getn(GetQuestData(quest, "BriefingSounds")) > 0) then 383 if (channel ~= -1) then 384 voice = table.getn(GetQuestData(quest, "BriefingSounds")) 385 StopChannel(channel) 386 end 387 end 388 menu:stop() 389 StopMusic() 390 end 391 ) 392 393 if (table.getn(GetQuestData(quest, "BriefingSounds")) > 0) then 394 function PlayNextVoice() 395 voice = voice + 1 396 if (voice <= table.getn(GetQuestData(quest, "BriefingSounds"))) then 397 channel = PlaySoundFile(GetQuestData(quest, "BriefingSounds")[voice], PlayNextVoice); 398 else 399 channel = -1 400 end 401 end 402 PlayNextVoice() 403 end 404 405 menu:run() 406end 407