share/hedgewars/Data/Scripts/Multiplayer/TechRacer.lua
changeset 13560 dc7b1a4ddded
parent 13559 3c562f52609c
child 13561 cba63f72e52f
equal deleted inserted replaced
13559:3c562f52609c 13560:dc7b1a4ddded
    25 
    25 
    26 ------------------
    26 ------------------
    27 -- Got Variables?
    27 -- Got Variables?
    28 ------------------
    28 ------------------
    29 
    29 
    30 local atkArray =
    30 local atkArray = {
    31 				{
    31 	{amBazooka, 	"amBazooka",		0},
    32 				{amBazooka, 	"amBazooka",		0},
    32 	{amBee, 	"amBee",		0},
    33 				{amBee, 		"amBee",			0},
    33 	{amMortar, 	"amMortar",		0},
    34 				{amMortar, 		"amMortar",			0},
    34 	{amDrill, 	"amDrill",		0},
    35 				{amDrill, 		"amDrill",			0},
    35 	{amSnowball, 	"amSnowball",		0},
    36 				{amSnowball, 	"amSnowball",		0},
    36 	{amGrenade,	"amGrenade",		0},
    37 
    37 	{amClusterBomb,	"amClusterBomb",	0},
    38 				{amGrenade,		"amGrenade",		0},
    38 	{amMolotov, 	"amMolotov",		0},
    39 				{amClusterBomb,	"amClusterBomb",	0},
    39 	{amWatermelon, 	"amWatermelon",		0},
    40 				{amMolotov, 	"amMolotov",		0},
    40 	{amHellishBomb,	"amHellishBomb",	0},
    41 				{amWatermelon, 	"amWatermelon",		0},
    41 	{amGasBomb, 	"amGasBomb",		0},
    42 				{amHellishBomb,	"amHellishBomb",	0},
    42 
    43 				{amGasBomb, 	"amGasBomb",		0},
    43 	{amShotgun,	"amShotgun",		0},
    44 
    44 	{amDEagle,	"amDEagle",		0},
    45 				{amShotgun,		"amShotgun",		0},
    45 	{amFlamethrower,"amFlamethrower",	0},
    46 				{amDEagle,		"amDEagle",			0},
    46 	{amSniperRifle,	"amSniperRifle",	0},
    47 				{amFlamethrower,"amFlamethrower",	0},
    47 	{amSineGun, 	"amSineGun",		0},
    48 				{amSniperRifle,	"amSniperRifle",	0},
    48 	{amIceGun, 	"amIceGun",		0},
    49 				{amSineGun, 	"amSineGun",		0},
    49 	{amLandGun,	"amLandGun",		0},
    50 				{amIceGun, 		"amIceGun",			0},
    50 
    51 				{amLandGun,		"amLandGun",		0},
    51 	{amFirePunch, 	"amFirePunch",		0},
    52 
    52 	{amWhip,	"amWhip",		0},
    53 				{amFirePunch, 	"amFirePunch",		0},
    53 	{amBaseballBat, "amBaseballBat",	0},
    54 				{amWhip,		"amWhip",			0},
    54 	{amKamikaze, 	"amKamikaze",		0},
    55 				{amBaseballBat, "amBaseballBat",	0},
    55 	{amSeduction, 	"amSeduction",		0},
    56 				{amKamikaze, 	"amKamikaze",		0},
    56 	{amHammer,	"amHammer",		0},
    57 				{amSeduction, 	"amSeduction",		0},
    57 
    58 				{amHammer,		"amHammer",			0},
    58 	{amMine, 	"amMine",		0},
    59 
    59 	{amDynamite, 	"amDynamite",		0},
    60 				{amMine, 		"amMine",			0},
    60 	{amCake, 	"amCake",		0},
    61 				{amDynamite, 	"amDynamite",		0},
    61 	{amBallgun, 	"amBallgun",		0},
    62 				{amCake, 		"amCake",			0},
    62 	{amRCPlane,	"amRCPlane",		0},
    63 				{amBallgun, 	"amBallgun",		0},
    63 	{amSMine,	"amSMine",		0},
    64 				{amRCPlane,		"amRCPlane",		0},
    64 	{amAirMine,	"amAirMine",		0},
    65 				{amSMine,		"amSMine",			0},
    65 
    66 				{amAirMine,		"amAirMine",		0},
    66 	{amAirAttack,	"amAirAttack",		0},
    67 
    67 	{amMineStrike,	"amMineStrike",		0},
    68 				{amAirAttack,	"amAirAttack",		0},
    68 	{amDrillStrike,	"amDrillStrike",	0},
    69 				{amMineStrike,	"amMineStrike",		0},
    69 	{amAirMine,	"amAirMine",		0},
    70 				{amDrillStrike,	"amDrillStrike",	0},
    70 	{amNapalm, 	"amNapalm",		0},
    71 				{amAirMine,		"amAirMine",		0},
    71 	{amPiano,	"amPiano",		0},
    72 				{amNapalm, 		"amNapalm",			0},
    72 
    73 				{amPiano,		"amPiano",			0},
    73 	{amKnife,	"amKnife",		0},
    74 
    74 
    75 				{amKnife,		"amKnife",			0},
    75 	{amBirdy,	"amBirdy",		0}
    76 
    76 }
    77 				{amBirdy,		"amBirdy",			0}
    77 
    78 
    78 local utilArray = {
    79 				}
    79 	{amBlowTorch, 	"amBlowTorch",		0},
    80 
    80 	{amPickHammer,	"amPickHammer",		0},
    81 local utilArray =
    81 	{amGirder, 	"amGirder",		0},
    82 				{
    82 	{amRubber, 	"amRubber",		0},
    83 				{amBlowTorch, 		"amBlowTorch",		0},
    83 	{amPortalGun,	"amPortalGun",		0},
    84 				{amPickHammer,		"amPickHammer",		0},
    84 
    85 				{amGirder, 			"amGirder",			0},
    85 	{amRope, 	"amRope",		0},
    86 				{amRubber, 			"amRubber",			0},
    86 	{amParachute, 	"amParachute",		0},
    87 				{amPortalGun,		"amPortalGun",		0},
    87 	{amTeleport,	"amTeleport",		0},
    88 
    88 	{amJetpack,	"amJetpack",		0},
    89 				{amRope, 			"amRope",			0},
    89 
    90 				{amParachute, 		"amParachute",		0},
    90 	{amInvulnerable,"amInvulnerable",	0},
    91 				{amTeleport,		"amTeleport",		0},
    91 	{amLaserSight,	"amLaserSight",		0},
    92 				{amJetpack,			"amJetpack",		0},
    92 	{amVampiric,	"amVampiric",		0},
    93 
    93 
    94 				{amInvulnerable,	"amInvulnerable",	0},
    94 	{amLowGravity, 	"amLowGravity",		0},
    95 				{amLaserSight,		"amLaserSight",		0},
    95 	{amExtraDamage, "amExtraDamage",	0},
    96 				{amVampiric,		"amVampiric",		0},
    96 	{amExtraTime,	"amExtraTime",		0},
    97 
    97 
    98 				{amLowGravity, 		"amLowGravity",		0},
    98 	{amResurrector, "amResurrector",	0},
    99 				{amExtraDamage, 	"amExtraDamage",	0},
    99 	{amTardis, 	"amTardis",		0},
   100 				{amExtraTime,		"amExtraTime",		0},
   100 
   101 
   101 	{amSwitch,	"amSwitch",		0}
   102 				{amResurrector, 	"amResurrector",	0},
   102 }
   103 				{amTardis, 			"amTardis",			0},
       
   104 
       
   105 				{amSwitch,			"amSwitch",			0}
       
   106 				}
       
   107 
   103 
   108 local activationStage = 0
   104 local activationStage = 0
   109 local jet = nil
   105 local jet = nil
   110 portalDistance = 5000
   106 portalDistance = 5000
   111 ufoFuel = 0
   107 ufoFuel = 0
   181 -- general methods
   177 -- general methods
   182 -------------------
   178 -------------------
   183 
   179 
   184 function RebuildTeamInfo()
   180 function RebuildTeamInfo()
   185 
   181 
   186 
   182 	-- make a list of individual team names
   187         -- make a list of individual team names
   183 	for i = 0, (TeamsCount-1) do
   188         for i = 0, (TeamsCount-1) do
   184 		teamNameArr[i] = " " -- = i
   189                 teamNameArr[i] = " " -- = i
   185 		teamSize[i] = 0
   190                 teamSize[i] = 0
   186 		teamIndex[i] = 0
   191                 teamIndex[i] = 0
   187 		teamScore[i] = 1000000
   192                 teamScore[i] = 1000000
   188 	end
   193         end
   189 	numTeams = 0
   194         numTeams = 0
   190 
   195 
   191 	for i = 0, (numhhs-1) do
   196         for i = 0, (numhhs-1) do
   192 
   197 
   193 		z = 0
   198                 z = 0
   194 		unfinished = true
   199                 unfinished = true
   195 		while(unfinished == true) do
   200                 while(unfinished == true) do
   196 
   201 
   197 			newTeam = true
   202                         newTeam = true
   198 			tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
   203                         tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
   199 
   204 
   200 			if tempHogTeamName == teamNameArr[z] then
   205                         if tempHogTeamName == teamNameArr[z] then
   201 				newTeam = false
   206                                 newTeam = false
   202 				unfinished = false
   207                                 unfinished = false
   203 			end
   208                         end
   204 
   209 
   205 			z = z + 1
   210                         z = z + 1
   206 
   211 
   207 			if z == TeamsCount then
   212                         if z == TeamsCount then
   208 				unfinished = false
   213                                 unfinished = false
   209 				if newTeam == true then
   214                                 if newTeam == true then
   210 					teamNameArr[numTeams] = tempHogTeamName
   215                                         teamNameArr[numTeams] = tempHogTeamName
   211 					numTeams = numTeams + 1
   216                                         numTeams = numTeams + 1
   212 				end
   217                                 end
   213 			end
   218                         end
   214 
   219 
   215 		end
   220                 end
   216 
   221 
   217 	end
   222         end
   218 
   223 
   219 	-- find out how many hogs per team, and the index of the first hog in hhs
   224         -- find out how many hogs per team, and the index of the first hog in hhs
   220 	for i = 0, (numTeams-1) do
   225         for i = 0, (numTeams-1) do
   221 		for z = 0, (numhhs-1) do
   226                 for z = 0, (numhhs-1) do
   222 			if GetHogTeamName(hhs[z]) == teamNameArr[i] then
   227                         if GetHogTeamName(hhs[z]) == teamNameArr[i] then
   223 				teamClan[i] = GetHogClan(hhs[z])
   228                                 teamClan[i] = GetHogClan(hhs[z])
   224 				if teamSize[i] == 0 then
   229                                 if teamSize[i] == 0 then
   225 					teamIndex[i] = z -- should give starting index
   230                                         teamIndex[i] = z -- should give starting index
   226 				end
   231                                 end
   227 				teamSize[i] = teamSize[i] + 1
   232                                 teamSize[i] = teamSize[i] + 1
   228 				--add a pointer so this hog appears at i in hhs
   233                                 --add a pointer so this hog appears at i in hhs
   229 			end
   234                         end
   230 		end
   235                 end
   231 
   236 
   232 	end
   237         end
       
   238 
   233 
   239 end
   234 end
   240 
   235 
   241 
   236 
   242 -----------------
   237 -----------------
   244 -----------------
   239 -----------------
   245 
   240 
   246 -- Returns min opacity, max opacity and flashing speed (`FrameTicks`)
   241 -- Returns min opacity, max opacity and flashing speed (`FrameTicks`)
   247 -- for the waypoint visual gears
   242 -- for the waypoint visual gears
   248 function FlashingHelper(wpIndex)
   243 function FlashingHelper(wpIndex)
   249         local minO, maxO, flashing
   244 	local minO, maxO, flashing
   250         if wpIndex == 0 then
   245 	if wpIndex == 0 then
   251                 -- Notable flashing of first waypoint
   246 		-- Notable flashing of first waypoint
   252                 minO, maxO = 92, 255
   247 		minO, maxO = 92, 255
   253                 flashing = 2
   248 		flashing = 2
   254         else
   249 	else
   255                 -- Slow pulsation
   250 		-- Slow pulsation
   256                 minO, maxO = 164, 224
   251 		minO, maxO = 164, 224
   257                 flashing = 10
   252 		flashing = 10
   258         end
   253 	end
   259 	return minO, maxO, flashing
   254 	return minO, maxO, flashing
   260 end
   255 end
   261 
   256 
   262 function CheckWaypoints()
   257 function CheckWaypoints()
   263 
   258 
   264         trackFinished = true
   259 	trackFinished = true
   265 
   260 
   266         for i = 0, (wpCount-1) do
   261 	for i = 0, (wpCount-1) do
   267 
   262 
   268                 g1X, g1Y = GetGearPosition(CurrentHedgehog)
   263 		g1X, g1Y = GetGearPosition(CurrentHedgehog)
   269                 g2X, g2Y = wpX[i], wpY[i]
   264 		g2X, g2Y = wpX[i], wpY[i]
   270 
   265 
   271                 g1X = g1X - g2X
   266 		g1X = g1X - g2X
   272                 g1Y = g1Y - g2Y
   267 		g1Y = g1Y - g2Y
   273                 dist = (g1X*g1X) + (g1Y*g1Y)
   268 		dist = (g1X*g1X) + (g1Y*g1Y)
   274 
   269 
   275                 NR = (48/100*wpRad)/2
   270 		NR = (48/100*wpRad)/2
   276 
   271 
   277                 if dist < (NR*NR) and not gameOver then
   272 		if dist < (NR*NR) and not gameOver then
   278                         wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog))
   273 			wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog))
   279                         SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 64, 64, 1, 10, 0, wpRad, 5, wpCol[i])
   274 			SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 64, 64, 1, 10, 0, wpRad, 5, wpCol[i])
   280 
   275 
   281                         wpRem = 0
   276 			wpRem = 0
   282                         for k = 0, (wpCount-1) do
   277 			for k = 0, (wpCount-1) do
   283                                 if wpActive[k] == false then
   278 				if wpActive[k] == false then
   284                                         wpRem = wpRem + 1
   279 					wpRem = wpRem + 1
   285                                 end
   280 				end
   286                         end
   281 			end
   287 
   282 
   288                         if not wpActive[i] then
   283 			if not wpActive[i] then
   289                                 local wpMessage = ""
   284 				local wpMessage = ""
   290                                 if wpRem-1 == 0 then
   285 				if wpRem-1 == 0 then
   291                                         wpMessage = loc("Track completed!")
   286 					wpMessage = loc("Track completed!")
   292                                 else
   287 				else
   293                                         wpMessage = string.format(loc("Waypoints remaining: %d"), wpRem-1)
   288 					wpMessage = string.format(loc("Waypoints remaining: %d"), wpRem-1)
   294                                 end
   289 				end
   295                                 AddCaption(wpMessage, 0xffba00ff, capgrpGameState)
   290 				AddCaption(wpMessage, 0xffba00ff, capgrpGameState)
   296                         end
   291 			end
   297 
   292 
   298                         wpActive[i] = true
   293 			wpActive[i] = true
   299 
   294 
   300                 end
   295 		end
   301 
   296 
   302                 if wpActive[i] == false then
   297 		if wpActive[i] == false then
   303                         trackFinished = false
   298 			trackFinished = false
   304                 end
   299 		end
   305 
   300 
   306         end
   301 	end
   307 
   302 
   308         return(trackFinished)
   303 	return(trackFinished)
   309 
   304 
   310 end
   305 end
   311 
   306 
   312 function AdjustScores()
   307 function AdjustScores()
   313 
   308 
   314 	local bestTimeComment = loc("Did not finish")
   309 	local bestTimeComment = loc("Did not finish")
   315 
   310 
   316         newScore = false
   311 	newScore = false
   317 
   312 
   318         -- update this clan's time if the new track is better
   313 	-- update this clan's time if the new track is better
   319         for i = 0, (numTeams-1) do
   314 	for i = 0, (numTeams-1) do
   320                 if teamClan[i] == GetHogClan(CurrentHedgehog) then
   315 		if teamClan[i] == GetHogClan(CurrentHedgehog) then
   321                         if trackTime < teamScore[i] then
   316 			if trackTime < teamScore[i] then
   322                                 teamScore[i] = trackTime
   317 				teamScore[i] = trackTime
   323                                 newScore = true
   318 				newScore = true
   324                         else
   319 			else
   325                                 newScore = false
   320 				newScore = false
   326                         end
   321 			end
   327                 end
   322 		end
   328         end
   323 	end
   329 
   324 
   330         -- find the best time out of those so far
   325 	-- find the best time out of those so far
   331         for i = 0, (numTeams-1) do
   326 	for i = 0, (numTeams-1) do
   332                 if teamScore[i] < bestTime then
   327 		if teamScore[i] < bestTime then
   333                         bestTime = teamScore[i]
   328 			bestTime = teamScore[i]
   334                         bestClan = teamClan[i]
   329 			bestClan = teamClan[i]
   335                 end
   330 		end
   336         end
   331 	end
   337 
   332 
   338         if bestTime ~= 1000000 then
   333 	if bestTime ~= 1000000 then
   339                 bestTimeComment = string.format(loc("%.1fs"), (bestTime/1000))
   334 		bestTimeComment = string.format(loc("%.1fs"), (bestTime/1000))
   340         end
   335 	end
   341 
   336 
   342         if newScore == true then
   337 	if newScore == true then
   343                 if trackTime == bestTime then -- best time of the race
   338 		if trackTime == bestTime then -- best time of the race
   344                         ShowMission(loc("TechRacer"),
   339 			ShowMission(loc("TechRacer"),
   345                         loc("Track completed!"),
   340 			loc("Track completed!"),
   346                         string.format(loc("New race record: %.1fs"), (trackTime/1000)) .. "|" ..
   341 			string.format(loc("New race record: %.1fs"), (trackTime/1000)) .. "|" ..
   347                         string.format(loc("Winning time: %s"), bestTimeComment), 0, 4000)
   342 			string.format(loc("Winning time: %s"), bestTimeComment), 0, 4000)
   348                         PlaySound(sndHomerun)
   343 			PlaySound(sndHomerun)
   349                 else    -- best time for the clan
   344 		else    -- best time for the clan
   350                         ShowMission(loc("TechRacer"),
   345 			ShowMission(loc("TechRacer"),
   351                         loc("Track completed!"),
   346 			loc("Track completed!"),
   352                         string.format(loc("New clan record: %.1fs"), (trackTime/1000)) .. "|" ..
   347 			string.format(loc("New clan record: %.1fs"), (trackTime/1000)) .. "|" ..
   353                         string.format(loc("Winning time: %s"), bestTimeComment), 4, 4000)
   348 			string.format(loc("Winning time: %s"), bestTimeComment), 4, 4000)
   354                 end
   349 		end
   355         else -- not any kind of new score
   350 	else -- not any kind of new score
   356                 ShowMission(loc("TechRacer"),
   351 		ShowMission(loc("TechRacer"),
   357                 loc("Track completed!"),
   352 		loc("Track completed!"),
   358                 string.format(loc("Time: %.1fs"), (trackTime/1000)) .. "|" ..
   353 		string.format(loc("Time: %.1fs"), (trackTime/1000)) .. "|" ..
   359                 string.format(loc("Winning time: %s"), bestTimeComment), -amSkip, 4000)
   354 		string.format(loc("Winning time: %s"), bestTimeComment), -amSkip, 4000)
   360                 PlaySound(sndHellish)
   355 		PlaySound(sndHellish)
   361         end
   356 	end
   362 
   357 
   363         for i = 0, (TeamsCount-1) do
   358 	for i = 0, (TeamsCount-1) do
   364                 if teamNameArr[i] ~= " " and teamScore[i] ~= 1000000 then
   359 		if teamNameArr[i] ~= " " and teamScore[i] ~= 1000000 then
   365                         SetTeamLabel(teamNameArr[i], string.format(loc("%.1fs"), teamScore[i]/1000))
   360 			SetTeamLabel(teamNameArr[i], string.format(loc("%.1fs"), teamScore[i]/1000))
   366                 end
   361 		end
   367         end
   362 	end
   368 
   363 
   369         if bestTime == trackTime then
   364 	if bestTime == trackTime then
   370                 fastColour = GetClanColor(GetHogClan(CurrentHedgehog))
   365 		fastColour = GetClanColor(GetHogClan(CurrentHedgehog))
   371 
   366 
   372                 for i = 0, (currCount-1) do
   367 		for i = 0, (currCount-1) do
   373                         fastX[i] = currX[i]
   368 			fastX[i] = currX[i]
   374                         fastY[i] = currY[i]
   369 			fastY[i] = currY[i]
   375                 end
   370 		end
   376 
   371 
   377                 fastCount = currCount
   372 		fastCount = currCount
   378                 fastIndex = 0
   373 		fastIndex = 0
   379 
   374 
   380         else
   375 	else
   381                 currCount = 0
   376 		currCount = 0
   382                 fastIndex = 0
   377 		fastIndex = 0
   383         end
   378 	end
   384 
   379 
   385 
   380 
   386 end
   381 end
   387 
   382 
   388 function onNewRound()
   383 function onNewRound()
   389 
   384 
   390         roundNumber = roundNumber + 1
   385 	roundNumber = roundNumber + 1
   391 
   386 
   392         totalComment = ""
   387 	totalComment = ""
   393         for i = 0, (TeamsCount-1) do
   388 	for i = 0, (TeamsCount-1) do
   394                         if teamNameArr[i] ~= " " then
   389 		if teamNameArr[i] ~= " " then
   395 				if teamScore[i] ~= 1000000 then
   390 			if teamScore[i] ~= 1000000 then
   396                                 	teamComment[i] = string.format(loc("%s: %.1fs"), teamNameArr[i], (teamScore[i]/1000)) .. "|"
   391 				teamComment[i] = string.format(loc("%s: %.1fs"), teamNameArr[i], (teamScore[i]/1000)) .. "|"
   397 				else
   392 			else
   398                                 	teamComment[i] = string.format(loc("%s: Did not finish"), teamNameArr[i]) .. "|"
   393 				teamComment[i] = string.format(loc("%s: Did not finish"), teamNameArr[i]) .. "|"
   399 				end
   394 			end
   400                                 totalComment = totalComment .. teamComment[i]
   395 			totalComment = totalComment .. teamComment[i]
   401                         elseif teamNameArr[i] == " " then
   396 		elseif teamNameArr[i] == " " then
   402                                 teamComment[i] = "|"
   397 			teamComment[i] = "|"
   403                         end
   398 		end
   404         end
   399 	end
   405 
   400 
   406         ShowMission(    loc("TechRacer"),
   401 	ShowMission(loc("TechRacer"),
   407                                         loc("Status update"),
   402 		loc("Status update"),
   408                                         string.format(loc("Rounds complete: %d/%d"), roundNumber, roundLimit) .. "|" .. " " .. "|" ..
   403 		string.format(loc("Rounds complete: %d/%d"), roundNumber, roundLimit) .. "| |" ..
   409                                         loc("Best team times: ") .. "|" .. totalComment, 0, 4000)
   404 		loc("Best team times: ") .. "|" ..
   410 
   405 		totalComment,
   411         -- end game if its at round limit
   406 		0, 4000)
   412         if roundNumber >= roundLimit then
   407 
   413                 -- Sort the scores for the ranking list
   408 	-- end game if its at round limit
   414                 local unfinishedArray = {}
   409 	if roundNumber >= roundLimit then
   415                 local sortedTeams = {}
   410 		-- Sort the scores for the ranking list
   416                 local k = 1
   411 		local unfinishedArray = {}
   417                 for i = 0, TeamsCount-1 do
   412 		local sortedTeams = {}
   418                         if teamScore[i] ~= 1000000 and teamNameArr[i] ~= " " then
   413 		local k = 1
   419                                sortedTeams[k] = {}
   414 		for i = 0, TeamsCount-1 do
   420                                sortedTeams[k].name = teamNameArr[i]
   415 			if teamScore[i] ~= 1000000 and teamNameArr[i] ~= " " then
   421                                sortedTeams[k].score = teamScore[i]
   416 			       sortedTeams[k] = {}
   422                                k = k + 1
   417 			       sortedTeams[k].name = teamNameArr[i]
   423                         else
   418 			       sortedTeams[k].score = teamScore[i]
   424                                table.insert(unfinishedArray, string.format(loc("%s did not finish the race."), teamNameArr[i]))
   419 			       k = k + 1
   425                         end
   420 			else
   426                 end
   421 			       table.insert(unfinishedArray, string.format(loc("%s did not finish the race."), teamNameArr[i]))
   427                 table.sort(sortedTeams, function(team1, team2) return team1.score < team2.score end)
   422 			end
   428 
   423 		end
   429                 -- Write all the stats!
   424 		table.sort(sortedTeams, function(team1, team2) return team1.score < team2.score end)
   430 
   425 
   431                 for i = 1, #sortedTeams do
   426 		-- Write all the stats!
   432                         SendStat(siPointType, loc("milliseconds"))
   427 
   433                         SendStat(siPlayerKills, sortedTeams[i].score, sortedTeams[i].name)
   428 		for i = 1, #sortedTeams do
   434                 end
   429 			SendStat(siPointType, loc("milliseconds"))
   435 
   430 			SendStat(siPlayerKills, sortedTeams[i].score, sortedTeams[i].name)
   436                 if #sortedTeams >= 1 then
   431 		end
   437                         SendStat(siGameResult, string.format(loc("%s wins!"), sortedTeams[1].name))
   432 
   438                         SendStat(siCustomAchievement, string.format(loc("%s wins with a best time of %.1fs."), sortedTeams[1].name, (sortedTeams[1].score/1000)))
   433 		if #sortedTeams >= 1 then
   439                         for i=1,#unfinishedArray do
   434 			SendStat(siGameResult, string.format(loc("%s wins!"), sortedTeams[1].name))
   440                                  SendStat(siCustomAchievement, unfinishedArray[i])
   435 			SendStat(siCustomAchievement, string.format(loc("%s wins with a best time of %.1fs."), sortedTeams[1].name, (sortedTeams[1].score/1000)))
   441                         end
   436 			for i=1,#unfinishedArray do
   442                 else
   437 				 SendStat(siCustomAchievement, unfinishedArray[i])
   443                         SendStat(siGameResult, loc("Round draw"))
   438 			end
   444                         SendStat(siCustomAchievement, loc("Nobody managed to finish the race. What a shame!"))
   439 		else
   445                         SendStat(siCustomAchievement, loc("Maybe you should try an easier TechRacer map."))
   440 			SendStat(siGameResult, loc("Round draw"))
   446                 end
   441 			SendStat(siCustomAchievement, loc("Nobody managed to finish the race. What a shame!"))
       
   442 			SendStat(siCustomAchievement, loc("Maybe you should try an easier TechRacer map."))
       
   443 		end
   447 
   444 
   448 		-- Kill all the losers
   445 		-- Kill all the losers
   449 		for i = 0, (numhhs-1) do
   446 		for i = 0, (numhhs-1) do
   450 			if GetHogClan(hhs[i]) ~= bestClan then
   447 			if GetHogClan(hhs[i]) ~= bestClan then
   451 				SetEffect(hhs[i], heResurrectable, 0)
   448 				SetEffect(hhs[i], heResurrectable, 0)
   452 				SetHealth(hhs[i],0)
   449 				SetHealth(hhs[i],0)
   453 			end
   450 			end
   454 		end
   451 		end
   455 
   452 
   456 		gameOver = true
   453 		gameOver = true
   457                 for i=0, wpCount-1 do
   454 		for i=0, wpCount-1 do
   458                          -- Fade out waypoints
   455 			 -- Fade out waypoints
   459                          SetVisualGearValues(wpCirc[i], nil, nil, 0, 0, nil, 6)
   456 			 SetVisualGearValues(wpCirc[i], nil, nil, 0, 0, nil, 6)
   460                 end
   457 		end
   461 		EndTurn(true)
   458 		EndTurn(true)
   462         end
   459 	end
   463 
   460 
   464 end
   461 end
   465 
   462 
   466 function CheckForNewRound()
   463 function CheckForNewRound()
   467 
   464 
   468         if GetHogClan(CurrentHedgehog) == firstClan then
   465 	if GetHogClan(CurrentHedgehog) == firstClan then
   469                 onNewRound()
   466 		onNewRound()
   470         end
   467 	end
   471 
   468 
   472 end
   469 end
   473 
   470 
   474 function DisableTumbler(endTurn)
   471 function DisableTumbler(endTurn)
   475         if endTurn == nil then endTurn = true end
   472 	if endTurn == nil then endTurn = true end
   476         if racerActive then
   473 	if racerActive then
   477                 currCount = 0
   474 		currCount = 0
   478                 fastIndex = 0
   475 		fastIndex = 0
   479                 racerActive = false -- newadd
   476 		racerActive = false -- newadd
   480                 if endTurn then
   477 		if endTurn then
   481                          EndTurn(true)
   478 			 EndTurn(true)
   482                 end
   479 		end
   483 		if trackFinished and not gameOver then
   480 		if trackFinished and not gameOver then
   484                          for i=0, wpCount-1 do
   481 			 for i=0, wpCount-1 do
   485                        	         SetVisualGearValues(wpCirc[i], nil, nil, 255, 255, nil, 2)
   482 		       		 SetVisualGearValues(wpCirc[i], nil, nil, 255, 255, nil, 2)
   486                          end
   483 			 end
   487                 elseif not gameOver then
   484 		elseif not gameOver then
   488                          for i=0, wpCount-1 do
   485 			 for i=0, wpCount-1 do
   489                        	         SetVisualGearValues(wpCirc[i], nil, nil, 32, 32, nil, 1)
   486 		       		 SetVisualGearValues(wpCirc[i], nil, nil, 32, 32, nil, 1)
   490                          end
   487 			 end
   491                 end
   488 		end
   492         end
   489 	end
   493 end
   490 end
   494 
   491 
   495 function HandleGhost()
   492 function HandleGhost()
   496 
   493 
   497         -- get the current xy of the racer at this point
   494 	-- get the current xy of the racer at this point
   498         currX[currCount] = GetX(CurrentHedgehog)
   495 	currX[currCount] = GetX(CurrentHedgehog)
   499         currY[currCount] = GetY(CurrentHedgehog)
   496 	currY[currCount] = GetY(CurrentHedgehog)
   500         currCount = currCount + 1
   497 	currCount = currCount + 1
   501 
   498 
   502         -- draw a ping of smoke where the fastest player was at this point
   499 	-- draw a ping of smoke where the fastest player was at this point
   503         if (fastCount ~= 0) and (fastIndex < fastCount) then
   500 	if (fastCount ~= 0) and (fastIndex < fastCount) then
   504 
   501 
   505                 fastIndex = fastIndex + 1
   502 		fastIndex = fastIndex + 1
   506 
   503 
   507                 tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false)
   504 		tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false)
   508                 g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
   505 		g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
   509                 SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour )
   506 		SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour )
   510 
   507 
   511         end
   508 	end
   512 
   509 
   513 end
   510 end
   514 
   511 
   515 function BoomGirder(x,y,rot)
   512 function BoomGirder(x,y,rot)
   516 	girTime = 1
   513 	girTime = 1
   517 	if rot < 4 then
   514 	if rot < 4 then
   518 				AddGear(x, y, gtGrenade, 0, 0, 0, girTime)
   515 		AddGear(x, y, gtGrenade, 0, 0, 0, girTime)
   519 	elseif rot == 4 then
   516 	elseif rot == 4 then
   520 				g = AddGear(x-45, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   517 		g = AddGear(x-45, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   521 				g = AddGear(x-30, y, gtGrenade, 0, 0, 0, girTime)
   518 		g = AddGear(x-30, y, gtGrenade, 0, 0, 0, girTime)
   522 				g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   519 		g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   523 				g = AddGear(x+30, y, gtGrenade, 0, 0, 0, girTime)
   520 		g = AddGear(x+30, y, gtGrenade, 0, 0, 0, girTime)
   524 				g = AddGear(x+45, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   521 		g = AddGear(x+45, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   525 	elseif rot == 5 then ------- diag
   522 	elseif rot == 5 then ------- diag
   526 				g = AddGear(x+45, y+45, gtGrenade, 0, 0, 0, girTime) --n
   523 		g = AddGear(x+45, y+45, gtGrenade, 0, 0, 0, girTime) --n
   527 				g = AddGear(x+30, y+30, gtGrenade, 0, 0, 0, girTime)
   524 		g = AddGear(x+30, y+30, gtGrenade, 0, 0, 0, girTime)
   528 				g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   525 		g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   529 				g = AddGear(x-30, y-30, gtGrenade, 0, 0, 0, girTime)
   526 		g = AddGear(x-30, y-30, gtGrenade, 0, 0, 0, girTime)
   530 				g = AddGear(x-45, y-45, gtGrenade, 0, 0, 0, girTime) --n
   527 		g = AddGear(x-45, y-45, gtGrenade, 0, 0, 0, girTime) --n
   531 	elseif rot == 6 then
   528 	elseif rot == 6 then
   532 				g = AddGear(x, y-45, gtGrenade, 0, 0, 0, girTime) -- needed?
   529 		g = AddGear(x, y-45, gtGrenade, 0, 0, 0, girTime) -- needed?
   533 				g = AddGear(x, y+30, gtGrenade, 0, 0, 0, girTime)
   530 		g = AddGear(x, y+30, gtGrenade, 0, 0, 0, girTime)
   534 				g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   531 		g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   535 				g = AddGear(x, y-30, gtGrenade, 0, 0, 0, girTime)
   532 		g = AddGear(x, y-30, gtGrenade, 0, 0, 0, girTime)
   536 				g = AddGear(x, y+45, gtGrenade, 0, 0, 0, girTime) -- needed?
   533 		g = AddGear(x, y+45, gtGrenade, 0, 0, 0, girTime) -- needed?
   537 	elseif rot == 7 then -------
   534 	elseif rot == 7 then -------
   538 				g = AddGear(x+45, y-45, gtGrenade, 0, 0, 0, girTime) --n
   535 		g = AddGear(x+45, y-45, gtGrenade, 0, 0, 0, girTime) --n
   539 				g = AddGear(x+30, y-30, gtGrenade, 0, 0, 0, girTime)
   536 		g = AddGear(x+30, y-30, gtGrenade, 0, 0, 0, girTime)
   540 				g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   537 		g = AddGear(x, y, gtGrenade, 0, 0, 0, girTime) -- needed?
   541 				g = AddGear(x-30, y+30, gtGrenade, 0, 0, 0, girTime)
   538 		g = AddGear(x-30, y+30, gtGrenade, 0, 0, 0, girTime)
   542 				g = AddGear(x-45, y+45, gtGrenade, 0, 0, 0, girTime) --n
   539 		g = AddGear(x-45, y+45, gtGrenade, 0, 0, 0, girTime) --n
   543 	end
   540 	end
   544 end
   541 end
   545 
   542 
   546 function RemoveGear(gear)
   543 function RemoveGear(gear)
   547 	if (isATrackedGear(gear) == true) and (GetGearType(gear) ~= gtHedgehog) then
   544 	if (isATrackedGear(gear) == true) and (GetGearType(gear) ~= gtHedgehog) then
   548 		DeleteGear(gear)
   545 		DeleteGear(gear)
   549 	end
   546 	end
   550 end
   547 end
   551 
   548 
   552 function ClearMap()
   549 function ClearMap()
   553 
       
   554 	runOnGears(RemoveGear)
   550 	runOnGears(RemoveGear)
   555 
       
   556 end
   551 end
   557 
   552 
   558 function CallBob(x,y)
   553 function CallBob(x,y)
   559 	if not racerActive and not gameOver then
   554 	if not racerActive and not gameOver then
   560         if wpCount == 0 or wpX[wpCount - 1] ~= x or wpY[wpCount - 1] ~= y then
   555 		if wpCount == 0 or wpX[wpCount - 1] ~= x or wpY[wpCount - 1] ~= y then
   561 
   556 
   562             wpX[wpCount] = x
   557 			wpX[wpCount] = x
   563             wpY[wpCount] = y
   558 			wpY[wpCount] = y
   564             wpCol[wpCount] = 0xffffffff
   559 			wpCol[wpCount] = 0xffffffff
   565             wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true)
   560 			wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true)
   566 
   561 
   567             local minO, maxO, flashing = FlashingHelper(wpCount)
   562 			local minO, maxO, flashing = FlashingHelper(wpCount)
   568             -- Make first waypoint flash very noticably before the hog starts racing
   563 			-- Make first waypoint flash very noticably before the hog starts racing
   569             SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], minO, maxO, 1, flashing, 0, wpRad, 5, wpCol[wpCount])
   564 			SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], minO, maxO, 1, flashing, 0, wpRad, 5, wpCol[wpCount])
   570 
   565 
   571             wpCount = wpCount + 1
   566 			wpCount = wpCount + 1
   572         end
   567 		end
   573     end
   568 	end
   574 end
   569 end
   575 
   570 
   576 
   571 
   577 
   572 
   578 function HandleFreshMapCreation()
   573 function HandleFreshMapCreation()
   597 	if gameOver then
   592 	if gameOver then
   598 		for i = 0,(wpCount-1) do
   593 		for i = 0,(wpCount-1) do
   599 			SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 164, 224, 1, 10, 0, wpRad, 5, wpCol[wpCount])
   594 			SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 164, 224, 1, 10, 0, wpRad, 5, wpCol[wpCount])
   600 		end
   595 		end
   601 
   596 
   602         else
   597 	else
   603 		for i = 0,(wpCount-1) do
   598 		for i = 0,(wpCount-1) do
   604 			DeleteVisualGear(wpCirc[i])
   599 			DeleteVisualGear(wpCirc[i])
   605 		end
   600 		end
   606 		wpCount = 0
   601 		wpCount = 0
   607 
   602 
   620 
   615 
   621 end
   616 end
   622 
   617 
   623 function TryRepositionHogs()
   618 function TryRepositionHogs()
   624 
   619 
   625         if MapHasBorder() == true then
   620 	if MapHasBorder() == true then
   626 
   621 
   627                 for i = 0, (numhhs-1) do
   622 		for i = 0, (numhhs-1) do
   628                         if hhs[i] ~= nil then
   623 			if hhs[i] ~= nil then
   629                                 SetGearPosition(hhs[i],GetX(hhs[i]), TopY-10)
   624 				SetGearPosition(hhs[i],GetX(hhs[i]), TopY-10)
   630                         end
   625 			end
   631                 end
   626 		end
   632 
   627 
   633         end
   628 	end
   634 
   629 
   635 end
   630 end
   636 
   631 
   637 ----------------------------------
   632 ----------------------------------
   638 -- GAME METHODS / EVENT HANDLERS
   633 -- GAME METHODS / EVENT HANDLERS
   655 
   650 
   656 end
   651 end
   657 
   652 
   658 function onGameInit()
   653 function onGameInit()
   659 
   654 
   660     TemplateFilter = 0
   655 	TemplateFilter = 0
   661 
   656 
   662     if MapGen == mgDrawn then
   657 	if MapGen == mgDrawn then
   663         eraseMap(false)
   658 		eraseMap(false)
   664     else
   659 	else
   665         MapGen = mgDrawn
   660 		MapGen = mgDrawn
   666     end
   661 	end
   667 
   662 
   668     if mapID == nil then
   663 	if mapID == nil then
   669         mapID = 2 + GetRandom(7)
   664 		mapID = 2 + GetRandom(7)
   670     end
   665 	end
   671 
   666 
   672     addHashData(mapID)
   667 	addHashData(mapID)
   673 
   668 
   674     Theme = "Cave"
   669 	Theme = "Cave"
   675     Map = ""
   670 	Map = ""
   676 
   671 
   677     EnableGameFlags(gfInfAttack, gfDisableWind, gfBorder)
   672 	EnableGameFlags(gfInfAttack, gfDisableWind, gfBorder)
   678     DisableGameFlags(gfSolidLand)
   673 	DisableGameFlags(gfSolidLand)
   679     CaseFreq = 0
   674 	CaseFreq = 0
   680     TurnTime = 90000
   675 	TurnTime = 90000
   681     WaterRise = 0
   676 	WaterRise = 0
   682     HealthDecrease = 0
   677 	HealthDecrease = 0
   683 
   678 
   684     for x = 1, 16 do
   679 	for x = 1, 16 do
   685         AddPoint(x*100,100,5)
   680 		AddPoint(x*100,100,5)
   686     end
   681 	end
   687 
   682 
   688     FlushPoints()
   683 	FlushPoints()
   689 
   684 
   690 end
   685 end
   691 
   686 
   692 function limitHogs(gear)
   687 function limitHogs(gear)
   693 
   688 
   694 	cnthhs = cnthhs + 1
   689 	cnthhs = cnthhs + 1
   695 	if cnthhs > 1 then
   690 	if cnthhs > 1 then
   696 		DeleteGear(gear)
   691 		DeleteGear(gear)
   697     end
   692 	end
   698 
   693 
   699 end
   694 end
   700 
   695 
   701 function onSpecialPoint(x,y,flag)
   696 function onSpecialPoint(x,y,flag)
   702     if flag == 99 then
   697 	if flag == 99 then
   703         fastX[fastCount] = x
   698 		fastX[fastCount] = x
   704         fastY[fastCount] = y
   699 		fastY[fastCount] = y
   705         fastCount = fastCount + 1
   700 		fastCount = fastCount + 1
   706     elseif flag == 0 then
   701 	elseif flag == 0 then
   707         techX[techCount], techY[techCount] = x, y
   702 		techX[techCount], techY[techCount] = x, y
   708         techCount = techCount + 1
   703 		techCount = techCount + 1
   709     else
   704 	else
   710         addHashData(x)
   705 		addHashData(x)
   711         addHashData(y)
   706 		addHashData(y)
   712         addHashData(flag)
   707 		addHashData(flag)
   713         specialPointsX[specialPointsCount] = x
   708 		specialPointsX[specialPointsCount] = x
   714         specialPointsY[specialPointsCount] = y
   709 		specialPointsY[specialPointsCount] = y
   715         specialPointsFlag[specialPointsCount] = flag
   710 		specialPointsFlag[specialPointsCount] = flag
   716         specialPointsCount = specialPointsCount + 1
   711 		specialPointsCount = specialPointsCount + 1
   717     end
   712 	end
   718 end
   713 end
   719 
   714 
   720 function InterpretPoints()
   715 function InterpretPoints()
   721 
   716 
   722 	-- flags run from 0 to 127
   717 	-- flags run from 0 to 127
   870 	SendGameResultOff()
   865 	SendGameResultOff()
   871 	SendRankingStatsOff()
   866 	SendRankingStatsOff()
   872 	SendAchievementsStatsOff()
   867 	SendAchievementsStatsOff()
   873 	SendHealthStatsOff()
   868 	SendHealthStatsOff()
   874 
   869 
   875 		trackTeams()
   870 	trackTeams()
   876 
   871 
   877 		roundN = 0
   872 	roundN = 0
   878         lastRound = TotalRounds
   873 	lastRound = TotalRounds
   879         RoundHasChanged = false
   874 	RoundHasChanged = false
   880 
   875 
   881 	    RebuildTeamInfo()
   876 	RebuildTeamInfo()
   882 
   877 
   883 		for i=0 , TeamsCount - 1 do
   878 	for i=0 , TeamsCount - 1 do
   884 			cnthhs = 0
   879 		cnthhs = 0
   885 			runOnHogsInTeam(limitHogs, teamNameArr[i])
   880 		runOnHogsInTeam(limitHogs, teamNameArr[i])
   886 		end
   881 	end
   887 
   882 
   888         ShowMission     (
   883 	ShowMission(
   889                                 loc("TechRacer"),
   884 		loc("TechRacer"),
   890                                 loc("A Hedgewars mini-game"),
   885 		loc("A Hedgewars mini-game"),
   891 
   886 
   892                         	loc("Complete the track as fast as you can!") .. "|" ..
   887 		loc("Complete the track as fast as you can!") .. "|" ..
   893                                 loc("Round limit:") .. " " .. roundLimit .. "|" ..
   888 		loc("Round limit:") .. " " .. roundLimit .. "|" ..
   894 				loc("You can further customize the race by changing the scheme script parameter.") .. "|" ..
   889 		loc("You can further customize the race by changing the scheme script parameter.") .. "|",
   895 
   890 		4, 4000
   896                                 "", 4, 4000
   891 		)
   897                                 )
   892 
   898 
   893 	TryRepositionHogs()
   899         TryRepositionHogs()
   894 
   900 
   895 	activationStage = 1
   901 		activationStage = 1
   896 	HandleFreshMapCreation()
   902 		HandleFreshMapCreation()
       
   903 
   897 
   904 end
   898 end
   905 
   899 
   906 
   900 
   907 
   901 
   908 function onNewTurn()
   902 function onNewTurn()
   909 
   903 
   910         CheckForNewRound()
   904 	CheckForNewRound()
   911         TryRepositionHogs()
   905 	TryRepositionHogs()
   912 
   906 
   913         racerActive = false
   907 	racerActive = false
   914 
   908 
   915 		activationStage = 1
   909 	activationStage = 1
   916 
   910 
   917         trackTime = 0
   911 	trackTime = 0
   918 
   912 
   919         currCount = 0 -- hopefully this solves problem
   913 	currCount = 0 -- hopefully this solves problem
   920         gTimer = 0
   914 	gTimer = 0
   921 
   915 
   922         -- Set the waypoints to unactive on new round
   916 	-- Set the waypoints to unactive on new round
   923         if not gameOver then
   917 	if not gameOver then
   924                 for i = 0,(wpCount-1) do
   918 		for i = 0,(wpCount-1) do
   925                         wpActive[i] = false
   919 			wpActive[i] = false
   926                         wpCol[i] = 0xffffffff
   920 			wpCol[i] = 0xffffffff
   927                         local minO, maxO, flashing = FlashingHelper(i)
   921 			local minO, maxO, flashing = FlashingHelper(i)
   928                         SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], minO, maxO, 1, flashing, 0, wpRad, 5, wpCol[i])
   922 			SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], minO, maxO, 1, flashing, 0, wpRad, 5, wpCol[i])
   929                 end
   923 		end
   930         end
   924 	end
   931 
   925 
   932         -- Handle Starting Stage of Game
   926 	-- Handle Starting Stage of Game
   933         if (gameOver == false) and (gameBegun == false) then
   927 	if (gameOver == false) and (gameBegun == false) then
   934                         gameBegun = true
   928 		gameBegun = true
   935                         roundNumber = 0
   929 		roundNumber = 0
   936                         firstClan = GetHogClan(CurrentHedgehog)
   930 		firstClan = GetHogClan(CurrentHedgehog)
   937         end
   931 	end
   938 
   932 
   939         if gameOver == true then
   933 	if gameOver == true then
   940                 gameBegun = false
   934 		gameBegun = false
   941                 racerActive = false
   935 		racerActive = false
   942         end
   936 	end
   943 
   937 
   944         AddAmmo(CurrentHedgehog, amTardis, 0)
   938 	AddAmmo(CurrentHedgehog, amTardis, 0)
   945         AddAmmo(CurrentHedgehog, amDrillStrike, 0)
   939 	AddAmmo(CurrentHedgehog, amDrillStrike, 0)
   946         AddAmmo(CurrentHedgehog, amMineStrike, 0)
   940 	AddAmmo(CurrentHedgehog, amMineStrike, 0)
   947         AddAmmo(CurrentHedgehog, amNapalm, 0)
   941 	AddAmmo(CurrentHedgehog, amNapalm, 0)
   948         AddAmmo(CurrentHedgehog, amPiano, 0)
   942 	AddAmmo(CurrentHedgehog, amPiano, 0)
   949 
   943 
   950 end
   944 end
   951 
   945 
   952 function onGameTick20()
   946 function onGameTick20()
   953 
   947 
   954 		if (jet ~= nil) and (ufoFuel ~= 0) then
   948 	if (jet ~= nil) and (ufoFuel ~= 0) then
   955 			if ufoFuel == 2000 then
   949 		if ufoFuel == 2000 then
   956 				SetHealth(jet, 2000)
   950 			SetHealth(jet, 2000)
   957 			end
   951 		end
   958 		end
   952 	end
   959 
   953 
   960 		runOnGears(PortalEffects)
   954 	runOnGears(PortalEffects)
   961 
   955 
   962         -- airstrike detected, convert this into a potential waypoint spot
   956 	-- airstrike detected, convert this into a potential waypoint spot
   963         if cGear ~= nil then
   957 	if cGear ~= nil then
   964                 x,y = GetGearPosition(cGear)
   958 		x,y = GetGearPosition(cGear)
   965         if x > -9000 then
   959 		if x > -9000 then
   966             x,y = GetGearTarget(cGear)
   960 			x,y = GetGearTarget(cGear)
   967 
   961 
   968 
   962 			if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then
   969             if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then
   963 				AddCaption(loc("Please place the waypoint in the air and within the map boundaries"))
   970                 AddCaption(loc("Please place the waypoint in the air and within the map boundaries"))
   964 				PlaySound(sndDenied)
   971                 PlaySound(sndDenied)
   965 			elseif (y > WaterLine-50) then
   972             elseif (y > WaterLine-50) then
   966 				AddCaption(loc("Please place the waypoint further away from the waterline"))
   973                 AddCaption(loc("Please place the waypoint further away from the waterline"))
   967 				PlaySound(sndDenied)
   974                 PlaySound(sndDenied)
   968 			else
   975             else
   969 				CallBob(x, y)
   976                 CallBob(x, y)
   970 				if wpCount == wpLimit then
   977                 if wpCount == wpLimit then
   971 					AddCaption(loc("Race complexity limit reached"))
   978                     AddCaption(loc("Race complexity limit reached"))
   972 					DisableTumbler()
   979                     DisableTumbler()
   973 				end
   980                 end
   974 			end
   981             end
   975 		else
   982         else
   976 			DeleteGear(cGear)
   983             DeleteGear(cGear)
   977 		end
   984         end
   978 		SetGearPosition(cGear, -10000, 0)
   985         SetGearPosition(cGear, -10000, 0)
   979 	end
   986         end
       
   987 
   980 
   988 
   981 
   989 	if activationStage < 200 then
   982 	if activationStage < 200 then
   990 		HandleFreshMapCreation()
   983 		HandleFreshMapCreation()
   991 
   984 
   992                 if not gameOver and gameBegun and not racerActive then
   985 		if not gameOver and gameBegun and not racerActive then
   993 			if cameraGear then
   986 			if cameraGear then
   994 				DeleteGear(cameraGear)
   987 				DeleteGear(cameraGear)
   995 			end
   988 			end
   996 			-- Move camera to first waypoint.
   989 			-- Move camera to first waypoint.
   997 			-- We use a dummy gear to feed FollowGear. It does not affect the race.
   990 			-- We use a dummy gear to feed FollowGear. It does not affect the race.
   998 			cameraGear = AddGear(wpX[0], wpY[0], gtGenericFaller, 0, 0, 0, 5000)
   991 			cameraGear = AddGear(wpX[0], wpY[0], gtGenericFaller, 0, 0, 0, 5000)
   999 			SetState(cameraGear, bor(GetState(cameraGear), gstNoGravity+gstInvisible))
   992 			SetState(cameraGear, bor(GetState(cameraGear), gstNoGravity+gstInvisible))
  1000 			FollowGear(cameraGear)
   993 			FollowGear(cameraGear)
  1001                 end
   994 		end
  1002 
   995 
  1003 	end
   996 	end
  1004 
   997 
  1005 
   998 
  1006         -- start the player tumbling with a boom once their turn has actually begun
   999 	-- start the player tumbling with a boom once their turn has actually begun
  1007         if racerActive == false then
  1000 	if racerActive == false then
  1008 
  1001 
  1009                 if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
  1002 		if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
  1010 
  1003 
  1011                         -- if the gamehas started put the player in the middle of the first
  1004 			-- if the gamehas started put the player in the middle of the first
  1012                         -- waypoint that was placed
  1005 			-- waypoint that was placed
  1013                         if gameBegun == true then
  1006 			if gameBegun == true then
  1014                                 AddCaption(loc("Good to go!"))
  1007 				AddCaption(loc("Good to go!"))
  1015                                 racerActive = true
  1008 				racerActive = true
  1016                                 trackTime = 0
  1009 				trackTime = 0
  1017 
  1010 
  1018 
  1011 
  1019                                 SetGearPosition(CurrentHedgehog, wpX[0], wpY[0])
  1012 				SetGearPosition(CurrentHedgehog, wpX[0], wpY[0])
  1020                                 SetGearMessage(CurrentHedgehog,gmLeft)
  1013 				SetGearMessage(CurrentHedgehog,gmLeft)
  1021 
  1014 
  1022                                 FollowGear(CurrentHedgehog)
  1015 				FollowGear(CurrentHedgehog)
  1023 
  1016 
  1024                                 HideMission()
  1017 				HideMission()
  1025                                 activationStage = 201
  1018 				activationStage = 201
  1026                         end
  1019 			end
  1027 
  1020 
  1028                 end
  1021 		end
  1029 
  1022 
  1030         elseif (activationStage == 201) and (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
  1023 	elseif (activationStage == 201) and (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
  1031                 SetGearMessage(CurrentHedgehog,0)
  1024 		SetGearMessage(CurrentHedgehog,0)
  1032                 activationStage = 202
  1025 		activationStage = 202
  1033 	end
  1026 	end
  1034 
  1027 
  1035         -- has the player started his tumbling spree?
  1028 	-- has the player started his tumbling spree?
  1036         if (CurrentHedgehog ~= nil) then
  1029 	if (CurrentHedgehog ~= nil) then
  1037 
  1030 
  1038                 -- if the RACE has started, show tracktimes and keep tabs on waypoints
  1031 		-- if the RACE has started, show tracktimes and keep tabs on waypoints
  1039                 if (racerActive == true) and (activationStage == 202) then
  1032 		if (racerActive == true) and (activationStage == 202) then
  1040 
  1033 
  1041                         --ghost
  1034 			--ghost
  1042                         if GameTime%40 == 0 then
  1035 			if GameTime%40 == 0 then
  1043                                 HandleGhost()
  1036 				HandleGhost()
  1044                         end
  1037 			end
  1045 
  1038 
  1046                         trackTime = trackTime + 20
  1039 			trackTime = trackTime + 20
  1047 
  1040 
  1048                         if GameTime%100 == 0 then
  1041 			if GameTime%100 == 0 then
  1049 
  1042 
  1050                 		AddCaption(string.format(loc("Time: %.1fs"), (trackTime/1000)), GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
  1043 				AddCaption(string.format(loc("Time: %.1fs"), (trackTime/1000)), GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
  1051 
  1044 
  1052                                 if (CheckWaypoints() == true) then
  1045 				if (CheckWaypoints() == true) then
  1053                                         AdjustScores()
  1046 					AdjustScores()
  1054                                         DisableTumbler()
  1047 					DisableTumbler()
  1055                                 end
  1048 				end
  1056 
  1049 
  1057                         end
  1050 			end
  1058 
  1051 
  1059                         -- If hedgehog is not controlled anymore, stop racing mode
  1052 			-- If hedgehog is not controlled anymore, stop racing mode
  1060                         if band(GetState(CurrentHedgehog), gstHHDriven) == 0 then
  1053 			if band(GetState(CurrentHedgehog), gstHHDriven) == 0 then
  1061                                 DisableTumbler(false)
  1054 				DisableTumbler(false)
  1062                         end
  1055 			end
  1063 
  1056 
  1064                 end
  1057 		end
  1065 
  1058 
  1066         end
  1059 	end
  1067 
  1060 
  1068 end
  1061 end
  1069 
  1062 
  1070 -- handle short range portal gun
  1063 -- handle short range portal gun
  1071 function PortalEffects(gear)
  1064 function PortalEffects(gear)
  1114 
  1107 
  1115 end
  1108 end
  1116 
  1109 
  1117 function onGearResurrect(gear)
  1110 function onGearResurrect(gear)
  1118 
  1111 
  1119         AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
  1112 	AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
  1120 
  1113 
  1121         if gear == CurrentHedgehog then
  1114 	if gear == CurrentHedgehog then
  1122                DisableTumbler(false)
  1115 	       DisableTumbler(false)
  1123         end
  1116 	end
  1124 
  1117 
  1125 end
  1118 end
  1126 
  1119 
  1127 function isATrackedGear(gear)
  1120 function isATrackedGear(gear)
  1128 	if 	(GetGearType(gear) == gtHedgehog) or
  1121 	if 	(GetGearType(gear) == gtHedgehog) or
  1148 		trackGear(gear)
  1141 		trackGear(gear)
  1149 
  1142 
  1150 		if GetGearType(gear) == gtPortal then
  1143 		if GetGearType(gear) == gtPortal then
  1151 			setGearValue(gear,"life",portalDistance)
  1144 			setGearValue(gear,"life",portalDistance)
  1152 		elseif GetGearType(gear) == gtHedgehog then
  1145 		elseif GetGearType(gear) == gtHedgehog then
  1153             hhs[numhhs] = gear
  1146 			hhs[numhhs] = gear
  1154             numhhs = numhhs + 1
  1147 			numhhs = numhhs + 1
  1155             SetEffect(gear, heResurrectable, 1)
  1148 			SetEffect(gear, heResurrectable, 1)
  1156 		end
  1149 		end
  1157 
  1150 
  1158 	end
  1151 	end
  1159 
  1152 
  1160 	if GetGearType(gear) == gtAirAttack then
  1153 	if GetGearType(gear) == gtAirAttack then
  1161        cGear = gear
  1154 		cGear = gear
  1162 	elseif GetGearType(gear) == gtJetpack then
  1155 	elseif GetGearType(gear) == gtJetpack then
  1163 		jet = gear
  1156 		jet = gear
  1164 		if (ufoFuel ~= 0) then
  1157 		if (ufoFuel ~= 0) then
  1165 			SetHealth(jet, ufoFuel)
  1158 			SetHealth(jet, ufoFuel)
  1166 		end
  1159 		end
  1169 
  1162 
  1170 end
  1163 end
  1171 
  1164 
  1172 function onGearDelete(gear)
  1165 function onGearDelete(gear)
  1173 
  1166 
  1174         if isATrackedGear(gear) then
  1167 	if isATrackedGear(gear) then
  1175 		trackDeletion(gear)
  1168 		trackDeletion(gear)
  1176 	elseif GetGearType(gear) == gtAirAttack then
  1169 	elseif GetGearType(gear) == gtAirAttack then
  1177                 cGear = nil
  1170 		cGear = nil
  1178         elseif GetGearType(gear) == gtJetpack then
  1171 	elseif GetGearType(gear) == gtJetpack then
  1179 		jet = nil
  1172 		jet = nil
  1180 	elseif gear == cameraGear then
  1173 	elseif gear == cameraGear then
  1181 		cameraGear = nil
  1174 		cameraGear = nil
  1182 	end
  1175 	end
  1183 
  1176 
  1184 end
  1177 end
  1185 
  1178 
  1186 function onAttack()
  1179 function onAttack()
  1187     at = GetCurAmmoType()
  1180 	at = GetCurAmmoType()
  1188 
  1181 
  1189     usedWeapons[at] = 0
  1182 	usedWeapons[at] = 0
  1190 end
  1183 end
  1191 
  1184 
  1192 function onAchievementsDeclaration()
  1185 function onAchievementsDeclaration()
  1193     usedWeapons[amSkip] = nil
  1186 	usedWeapons[amSkip] = nil
  1194     usedWeapons[amExtraTime] = nil
  1187 	usedWeapons[amExtraTime] = nil
  1195 
  1188 
  1196     usedRope = usedWeapons[amRope] ~= nil
  1189 	usedRope = usedWeapons[amRope] ~= nil
  1197     usedPortal = usedWeapons[amPortalGun] ~= nil
  1190 	usedPortal = usedWeapons[amPortalGun] ~= nil
  1198     usedSaucer = usedWeapons[amJetpack] ~= nil
  1191 	usedSaucer = usedWeapons[amJetpack] ~= nil
  1199 
  1192 
  1200     usedWeapons[amRope] = nil
  1193 	usedWeapons[amRope] = nil
  1201     usedWeapons[amPortalGun] = nil
  1194 	usedWeapons[amPortalGun] = nil
  1202     usedWeapons[amJetpack] = nil
  1195 	usedWeapons[amJetpack] = nil
  1203 
  1196 
  1204     usedOther = next(usedWeapons) ~= nil
  1197 	usedOther = next(usedWeapons) ~= nil
  1205 
  1198 
  1206     if usedOther then -- smth besides skip, rope, portal or saucer used
  1199 	if usedOther then -- smth besides skip, rope, portal or saucer used
  1207         raceType = "unknown race"
  1200 		raceType = "unknown race"
  1208     elseif usedRope and not usedPortal and not usedSaucer then
  1201 	elseif usedRope and not usedPortal and not usedSaucer then
  1209         raceType = "rope race"
  1202 		raceType = "rope race"
  1210     elseif not usedRope and usedPortal and not usedSaucer then
  1203 	elseif not usedRope and usedPortal and not usedSaucer then
  1211         raceType = "portal race"
  1204 		raceType = "portal race"
  1212     elseif not usedRope and not usedPortal and usedSaucer then
  1205 	elseif not usedRope and not usedPortal and usedSaucer then
  1213         raceType = "saucer race"
  1206 		raceType = "saucer race"
  1214     elseif (usedRope or usedPortal or usedSaucer or usedOther) == false then -- no weapons used at all?
  1207 	elseif (usedRope or usedPortal or usedSaucer or usedOther) == false then -- no weapons used at all?
  1215         raceType = "no tools race"
  1208 		raceType = "no tools race"
  1216     else -- at least two of rope, portal and saucer used
  1209 	else -- at least two of rope, portal and saucer used
  1217         raceType = "mixed race"
  1210 		raceType = "mixed race"
  1218     end
  1211 	end
  1219 
  1212 
  1220     map = detectMapWithDigest()
  1213 	map = detectMapWithDigest()
  1221 
  1214 
  1222     for i = 0, (numTeams-1) do
  1215 	for i = 0, (numTeams-1) do
  1223         if teamScore[i] < 1000000 then
  1216 		if teamScore[i] < 1000000 then
  1224             DeclareAchievement(raceType, teamNameArr[i], map, teamScore[i])
  1217 			DeclareAchievement(raceType, teamNameArr[i], map, teamScore[i])
  1225         end
  1218 		end
  1226     end
  1219 	end
  1227 
  1220 
  1228     if map ~= nil and fastCount > 0 then
  1221 	if map ~= nil and fastCount > 0 then
  1229         StartGhostPoints(fastCount)
  1222 		StartGhostPoints(fastCount)
  1230 
  1223 
  1231         for i = 0, (fastCount - 1) do
  1224 		for i = 0, (fastCount - 1) do
  1232             DumpPoint(fastX[i], fastY[i])
  1225 			DumpPoint(fastX[i], fastY[i])
  1233         end
  1226 		end
  1234     end
  1227 	end
  1235 
  1228 
  1236 end
  1229 end
  1237 
  1230 
  1238 function onAmmoStoreInit()
  1231 function onAmmoStoreInit()
  1239 
  1232 
  1246 	for i = 1, #utilArray do
  1239 	for i = 1, #utilArray do
  1247 		SetAmmo(utilArray[i][1], 0, 0, 0, 1)
  1240 		SetAmmo(utilArray[i][1], 0, 0, 0, 1)
  1248 	end
  1241 	end
  1249 
  1242 
  1250 end
  1243 end
  1251