share/hedgewars/Data/Scripts/SpeedShoppa.lua
changeset 11034 a9bafac12634
child 12229 d62d6f8ebef1
--- /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