# HG changeset patch # User mikade # Date 1438572252 -32400 # Node ID a9bafac1263456aed0e12d5d1da0a01fcaccd3b3 # Parent 2a5520837036e9a0d106e29396a5c08044fc6d70 Add Wuzzy's SpeedShoppa challenges. Update ChangeLog.txt diff -r 2a5520837036 -r a9bafac12634 ChangeLog.txt --- 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) diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_Hedgelove@2x.png Binary file share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_Hedgelove@2x.png has changed diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_Ropes@2x.png Binary file share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_Ropes@2x.png has changed diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_ShoppaKing@2x.png Binary file share/hedgewars/Data/Graphics/Missions/Training/Challenge_-_Speed_Shoppa_-_ShoppaKing@2x.png has changed diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Locale/missions_de.txt --- 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." + diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Locale/missions_en.txt --- 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 diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Missions/Training/Challenge_-_Speed_Shoppa_-_Hedgelove.lua --- /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) diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Missions/Training/Challenge_-_Speed_Shoppa_-_Ropes.lua --- /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) diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Missions/Training/Challenge_-_Speed_Shoppa_-_ShoppaKing.lua --- /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) diff -r 2a5520837036 -r a9bafac12634 share/hedgewars/Data/Scripts/SpeedShoppa.lua --- /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