--- a/ChangeLog.txt Sat Aug 01 00:13:05 2015 +0300
+++ b/ChangeLog.txt Mon Aug 03 12:24:12 2015 +0900
@@ -2,10 +2,13 @@
* bugfixes
0.9.21 -> 0.9.22
+ + Extensive changes to TechRacer: Variable terrain types, enhanced parameters, hwmap interpreter, fuel limiter, etc.
+ Map previews can now take script parameters into account and preview waypoints in TechRacer
+ Added a couple new flags
+ Small improvements to the interface and in-game chat
+ Divided teams options will now just be ignored when more/less than 2 teams, instead of displaying a fatal error
+ + Added 6 TechRacer maps to TechMaps
+ + Added 3 SpeedShoppa Challenges: Shoppa Love, Ropes and Crates, The Customer is King
* Generated bridges/girders are now connected better to the land mass
* Fixed rubberband sprite
* The game will now fallback to default voicepack if a team's voicepack is not locally installed. (Instead of rendering team voiceless)
Binary file share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_Hedgelove@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_Ropes@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_ShoppaKing@2x.png has changed
--- a/share/hedgewars/Data/Locale/missions_de.txt Sat Aug 01 00:13:05 2015 +0300
+++ b/share/hedgewars/Data/Locale/missions_de.txt Mon Aug 03 12:24:12 2015 +0900
@@ -76,3 +76,12 @@
ClimbHome.name=Herausforderung: Nach Hause klettern
ClimbHome.desc="Du bist weit von Zuhause weg und das Wasser steigt ständig. Klettere so hoch, wie du kannst!"
+Challenge_-_Speed_Shoppa_-_Hedgelove.name=Herausforderung: Seilliebe
+Challenge_-_Speed_Shoppa_-_Hedgelove.desc="Zeig deine Liebe zum Seilschwingen, sammle ein paar wenige Kisten auf dieser kleinen Karte ein."
+
+Challenge_-_Speed_Shoppa_-_Ropes.name=Herausforderung: Seile und Kisten
+Challenge_-_Speed_Shoppa_-_Ropes.desc="Nimm dein Seil, und sammle alle Kisten auf dieser mittelgroßen Karte ein."
+
+Challenge_-_Speed_Shoppa_-_ShoppaKing.name=Herausforderung: Der Kunde ist König
+Challenge_-_Speed_Shoppa_-_ShoppaKing.desc="Zeig, dass du dem Titel eines Königs würdig bist und sammle alle Kisten so schnell wie möglich mit deinem Seil auf dieser großen Karte ein."
+
--- a/share/hedgewars/Data/Locale/missions_en.txt Sat Aug 01 00:13:05 2015 +0300
+++ b/share/hedgewars/Data/Locale/missions_en.txt Mon Aug 03 12:24:12 2015 +0900
@@ -71,4 +71,13 @@
Target_Practice_-_Grenade_easy.desc="A warm-up training for the aspiring grenadier."
Target_Practice_-_Grenade_hard.name=Target Practice: Grenade (hard)
-Target_Practice_-_Grenade_hard.desc="This is nothing for greenhorns! We will place the targets at some really tricky positions."
\ No newline at end of file
+Target_Practice_-_Grenade_hard.desc="This is nothing for greenhorns! We will place the targets at some really tricky positions."
+
+Challenge_-_Speed_Shoppa_-_Hedgelove.name=Challenge: Shoppa Love
+Challenge_-_Speed_Shoppa_-_Hedgelove.desc="Show your love to rope and collect a few crates on a small map."
+
+Challenge_-_Speed_Shoppa_-_Ropes.name=Challenge: Ropes and Crates
+Challenge_-_Speed_Shoppa_-_Ropes.desc="Take your rope and collect all crates on this medium-sized map."
+
+Challenge_-_Speed_Shoppa_-_ShoppaKing.name=Challenge: The Customer is King
+Challenge_-_Speed_Shoppa_-_ShoppaKing.desc="Show you're worthy of a true king and collect all crates as fast as possible on this large map."
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Challenge_-_Speed_Shoppa_-_Hedgelove.lua Mon Aug 03 12:24:12 2015 +0900
@@ -0,0 +1,38 @@
+HedgewarsScriptLoad("/Scripts/SpeedShoppa.lua")
+
+local params = {}
+params.missionTitle = loc("Shoppa Love")
+params.teamName = loc("Team of Hearts")
+params.hogName = loc("Heartful")
+params.teamFlag = "cm_iluvu"
+params.teamGrave = "heart"
+params.hogHat = "pinksunhat"
+params.crateType = "health"
+params.faceLeft = true
+
+params.time = 45000
+params.map = "Hedgelove"
+params.theme = "Nature"
+
+params.hog_x = 410
+params.hog_y = 934
+params.crates = {
+ { x = 183, y = 710 },
+ { x = 202, y = 519 },
+ { x = 336, y = 356 },
+ { x = 658, y = 363 },
+ { x = 1029, y = 39 },
+ { x = 758, y = 879 },
+ { x = 1324, y = 896 },
+ { x = 1410, y = 390 },
+ { x = 1746, y = 348 },
+ { x = 1870, y = 538 },
+ { x = 1884, y = 723 },
+ { x = 1682, y = 970 },
+}
+params.extra_onGameStart = function()
+ PlaceGirder(394, 1000, 0)
+ PlaceGirder(1696, 1000, 0)
+end
+
+SpeedShoppaMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Challenge_-_Speed_Shoppa_-_Ropes.lua Mon Aug 03 12:24:12 2015 +0900
@@ -0,0 +1,43 @@
+HedgewarsScriptLoad("/Scripts/SpeedShoppa.lua")
+
+local params = {}
+params.missionTitle = loc("Ropes and Crates")
+params.teamName = loc("Shoppa Union")
+params.hogName = loc("Hook")
+params.teamFlag = "cm_shoppa"
+params.hogHat = "NoHat"
+
+params.time = 115000
+params.map = "Ropes"
+params.theme = "City"
+
+params.hog_x = 3754
+params.hog_y = 1742
+params.crates = {
+ { x = 3533, y = 1404 },
+ { x = 3884, y = 1048 },
+ { x = 3366, y = 664 },
+ { x = 3162, y = 630 },
+ { x = 2872, y = 402 },
+ { x = 3812, y = 322 },
+ { x = 3685, y = 34 },
+ { x = 3324, y = 540 },
+ { x = 2666, y = 224 },
+ { x = 2380, y = 1002 },
+ { x = 2224, y = 1008 },
+ { x = 2226, y = 854 },
+ { x = 3274, y = 1754 },
+ { x = 3016, y = 1278 },
+ { x = 2756, y = 1716 },
+ { x = 2334, y = 1756 },
+ { x = 1716, y = 1752 },
+ { x = 1526, y = 1464 },
+ { x = 356, y = 1734 },
+ { x = 598, y = 1444 },
+ { x = 1084, y = 1150 },
+ { x = 358, y = 834 },
+ { x = 936, y = 200 },
+ { x = 1540, y = 514 },
+}
+
+SpeedShoppaMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Challenge_-_Speed_Shoppa_-_ShoppaKing.lua Mon Aug 03 12:24:12 2015 +0900
@@ -0,0 +1,54 @@
+HedgewarsScriptLoad("/Scripts/SpeedShoppa.lua")
+
+local params = {}
+params.missionTitle = loc("The Customor is King")
+params.teamName = loc("Shoppa Union")
+params.hogName = loc("King Customer")
+params.teamFlag = "cm_shoppa"
+params.teamGrave = "money"
+params.hogHat = "crown"
+
+params.time = 160000
+params.map = "ShoppaKing"
+params.theme = "Castle"
+
+params.hog_x = 543
+params.hog_y = 1167
+params.crates = {
+ { x = 170, y = 172 },
+ { x = 216, y = 478 },
+ { x = 616, y = 966 },
+ { x = 291, y = 1898 },
+ { x = 486, y = 1965 },
+ { x = 852, y = 1289 },
+ { x = 1224, y = 1625 },
+ { x = 925, y = 584 },
+ { x = 2013, y = 141 },
+ { x = 2250, y = 351 },
+ { x = 2250, y = 537 },
+ { x = 2472, y = 513 },
+ { x = 1974, y = 459 },
+ { x = 1995, y = 1068 },
+ { x = 2385, y = 1788 },
+ { x = 1698, y = 1725 },
+ { x = 2913, y = 1092 },
+ { x = 3972, y = 1788 },
+ { x = 3762, y = 1635 },
+ { x = 2577, y = 1473 },
+ { x = 3612, y = 1068 },
+ { x = 3945, y = 687 },
+ { x = 2883, y = 618 },
+ { x = 3543, y = 471 },
+ { x = 3636, y = 306 },
+ { x = 3210, y = 321 },
+ { x = 3426, y = 126 },
+ { x = 3033, y = 1590 },
+ { x = 3774, y = 1341 },
+ { x = 1254, y = 297 },
+ { x = 1300, y = 1022 },
+ { x = 1410, y = 1292 },
+ { x = 868, y = 1812 },
+ { x = 3426, y = 954 },
+}
+
+SpeedShoppaMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Scripts/SpeedShoppa.lua Mon Aug 03 12:24:12 2015 +0900
@@ -0,0 +1,194 @@
+--[=[
+Speed Shoppa Mission Framework for Hedgewars
+
+This is a simple library intended to make setting up simple training missions a trivial
+task. The library has been created to reduce redundancy in Lua scripts.
+
+The framework generates complete and fully Speed Shoppa missions by just
+one function call.
+
+The missions generated by this script are all the same:
+- The player will get a team with a single hedgehog.
+- The team gets infinite ropes.
+- A fixed set of crates will spawn at predefined positions.
+- The mission ends successfully when all crates have been collected
+- The mission ends unsuccessfully when the time runs out or the hedgehog dies
+- When the mission ends, the time it took to finish the mission is shown
+
+To use this library, you first have to load it and to call SpeedShoppaMission once with
+the appropriate parameters. Really, that’s all!
+See the comment of SpeedShoppaMission for a specification of all parameters.
+
+]=]
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+
+--[[
+SpeedShoppaMission(params)
+
+This function sets up the *entire* mission and needs one argument: params.
+The argument “params” is a table containing fields which describe the training mission.
+ mandatory fields:
+ - map: the name of the map to be used
+ - theme: the name of the theme (does not need to be a standalone theme)
+ - time: the time limit in milliseconds
+ - crates: The coordinates of where the crates will be spawned.
+ It is a table containing tables containing coordinates of format
+ { x=value, y=value }. Example:
+ crates = {
+ { x = 324, y = 43 },
+ { x = 123, y = 56 },
+ { x = 6, y = 0 },
+ }
+ There must be at least 1 crate.
+
+ optional fields:
+ - missionTitle: the name of the mission (optional but highly recommended) (default: "Speed Shoppa")
+ - hogHat: hat of the hedgehog (default: "NoHat")
+ - hogName: name of the hedgehog (default: "Roper")
+ - teamName: name of the hedgehog’s team (default: "Shoppers")
+ - teamGrave: name of the hedgehog’s grave (default: "Statue")
+ - teamFlag: name of the team’s flag (default: "cm_shoppa")
+ - clanColor: color of the (only) clan (default: 0xFF0204, which is a red tone)
+ - goalText: A short string explaining the goal of the mission
+ (default: "Use your rope to collect all crates as fast as possible.")
+ - faceLeft: If true, the hog faces to the left initially, if false, it faces to the right.
+ (default: false (=right))
+ - crateType Specify the type of crate (this has no gameplay effect), pick one of
+ "ammo", "utility", "health". Default: "ammo"
+ - extra_onGameStart: A function which is called at the end of this script's onGameStart. It takes no parameters.
+ You could use this to spawn additional gears like girders or mines.
+ - extra_onGameInit: A function which is called at the end of this script's onGameInit.
+]]
+
+
+local playerHog
+local gameStarted = false
+local cratesCollected = 0
+local gameEnded = false
+local timeOut = false
+local hogHurt = false
+local endTime
+
+local crates
+
+function SpeedShoppaMission(params)
+ if params.hogHat == nil then params.hogHat = "NoHat" end
+ if params.hogName == nil then params.hogName = loc("Roper") end
+ if params.teamName == nil then params.teamName = loc("Shoppers") end
+ if params.goalText == nil then params.goalText = loc("Use your rope to collect all crates as fast as possible.") end
+ if params.missionTitle == nil then params.missionTitle = loc("Speed Shoppa") end
+ if params.clanColor == nil then params.clanColor = 0xFF0204 end
+ if params.teamGrave == nil then params.teamGrave = "Statue" end
+ if params.teamFlag == nil then params.teamFlag = "cm_shoppa" end
+ if params.extra_onGameInit == nil then params.extra_onGameInit = function() end end
+ if params.extra_onGameStart == nil then params.extra_onGameStart = function() end end
+ if params.faceLeft == nil then params.faceLeft = false end
+
+ crates = params.crates
+ startTime = params.time
+
+ _G.onGameInit = function()
+ GameFlags = gfDisableWind + gfOneClanMode + gfBorder + gfSolidLand
+ TurnTime = startTime
+ CaseFreq = 0
+ MinesNum = 0
+ Explosives = 0
+ Delay = 10
+ Theme = params.theme
+ Map = params.map
+
+ AddTeam(params.teamName, params.clanColor, params.teamGrave, "Castle", "Default", params.teamFlag)
+ playerHog = AddHog(params.hogName, 0, 1, params.hogHat)
+ HogTurnLeft(playerHog, params.faceLeft)
+
+ SetGearPosition(playerHog, params.hog_x, params.hog_y)
+
+ params.extra_onGameInit()
+ end
+
+ _G.onAmmoStoreInit = function()
+ SetAmmo(amRope, 9, 0, 0, 1)
+ end
+
+ _G.onGameStart = function()
+ SendHealthStatsOff()
+ ShowMission(params.missionTitle, loc("Challenge"), params.goalText, -amRope, 5000)
+ for i=1,#crates do
+ spawnCrate(crates[i].x, crates[i].y)
+ end
+ params.extra_onGameStart()
+ end
+
+ _G.onNewTurn = function()
+ SetWeapon(amRope)
+ gameStarted = true
+ end
+ _G.onGearDelete = function(gear)
+ if GetGearType(gear) == gtCase and not hogHurt and not timeOut then
+ cratesCollected = cratesCollected + 1
+ PlaySound(sndShotgunReload)
+ if cratesCollected == #crates then
+ endTime = TurnTimeLeft
+ finalize()
+ else
+ AddCaption(string.format(loc("%d crate(s) remaining"), #crates - cratesCollected))
+ end
+ elseif gear == playerHog then
+ finalize()
+ end
+ end
+
+ _G.onGearDamage = function(gear)
+ if gear == playerHog then
+ hogHurt = true
+ end
+ end
+
+
+ _G.onGameTick20 = function()
+ if TurnTimeLeft < 40 and TurnTimeLeft > 0 and gameStarted and not timeOut and not gameEnded then
+ timeOut = true
+ AddCaption(loc("Time's up!"))
+ SetHealth(playerHog, 0)
+ hogHurt = true
+ end
+ end
+
+ _G.finalize = function()
+ if not gameEnded then
+ if cratesCollected == #crates then
+ PlaySound(sndVictory, playerHog)
+ SetState(playerHog, bor(GetState(playerHog), gstWinner))
+ SetState(playerHog, band(GetState(playerHog), bnot(gstHHDriven)))
+ AddCaption(loc("Challenge completed!"))
+ SendStat(siGameResult, loc("Challenge completed!"))
+ SendStat(siPointType, loc("milliseconds"))
+ local time = startTime - endTime
+ SendStat(siPlayerKills, tostring(time), params.teamName)
+ SendStat(siCustomAchievement, string.format(loc("You have finished the challenge in %.3f s."), (time/1000)))
+ TurnTimeLeft = 0
+ else
+ SendStat(siGameResult, loc("Challenge failed!"))
+ SendStat(siPointType, loc("crate(s)"))
+ SendStat(siPlayerKills, tostring(cratesCollected), params.teamName)
+ SendStat(siCustomAchievement, string.format(loc("You have collected %d out of %d crate(s)."), cratesCollected, #crates))
+ end
+ gameEnded = true
+ EndGame()
+ end
+ end
+
+ _G.spawnCrate = function(x, y)
+ if params.crateType == "utility" then
+ SpawnFakeUtilityCrate(x, y, false, false)
+ elseif params.crateType == "ammo" then
+ SpawnFakeAmmoCrate(x, y, false, false)
+ elseif params.crateType == "health" then
+ SpawnFakeHealthCrate(x, y, false, false)
+ else
+ SpawnFakeAmmoCrate(x, y, false, false)
+ end
+ end
+
+end