Substitute broken Tumbler-based GaudyRacer with generic, map independant Racer.
authormikade
Sun, 11 Sep 2011 04:08:50 +0200
changeset 5845 b20a1e0a0e7e
parent 5844 fdf22a4843f7
child 5846 99e0dccf5529
Substitute broken Tumbler-based GaudyRacer with generic, map independant Racer. More changes/updates on this script to come.
share/hedgewars/Data/Scripts/Multiplayer/GaudyRacer.cfg
share/hedgewars/Data/Scripts/Multiplayer/GaudyRacer.lua
share/hedgewars/Data/Scripts/Multiplayer/Racer.cfg
share/hedgewars/Data/Scripts/Multiplayer/Racer.lua
--- a/share/hedgewars/Data/Scripts/Multiplayer/GaudyRacer.cfg	Sat Sep 10 21:23:12 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-Default
-Default
--- a/share/hedgewars/Data/Scripts/Multiplayer/GaudyRacer.lua	Sat Sep 10 21:23:12 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,730 +0,0 @@
-
-------------------------------------------
--- RACER
--- a crazy, map-independant racing script
--- by mikade
------------------------------------------
-
------------------------------------
---0.1: with apologies to tumbler
------------------------------------
--- added tumbler movement system
--- added weapon systems
--- added timer to stop tumbler
--- added racer circle arrays
--- added changing of circs on contact
--- added a "track complete" etc
-
------------------------------------
---0.2: for your racing convenience
------------------------------------
-
--- added resurrection
--- added team tracking
--- added proper scoring (hopefully, finally)
--- changed showmission icons to match feedback
--- changed circles to be netural colours, and then change to team col
--- cleaned up code
--- cleaned up gameplay: removing control on resurrect, trackcomplete, maxpointset etc
--- improved player feedback: race record, clan record, no record etc.
-
------------------------------------
---0.3: user-requested features
------------------------------------
-
--- hogs now start at the location of the first waypoint \o/
--- added sticky camera. Hog will no longer lose focus on explosions etc.
--- increased maximum complexity for tracks
-
------------------------------------
---0.4: user-requested features
------------------------------------
-
--- added movement trail
--- removed exploder weapon
--- removed mortar weapon
-
------------------------------------
--- 0.5 gaudy feature experimentation
------------------------------------
--- added a booster
--- added flame trail for booster
--- added and removed dx/dy on mortar launch
--- added and removed keypress-based mortar fire
--- changed mortar for a gtShell, probably more useful for tunneling
--- added dx/dy *2 shell fire
-
-----------------------------------
--- 0.6 modesty / display mod
-----------------------------------
--- author branding removed
--- version numbers removed
-
------------------------------
--- SCRIPT BEGINS
------------------------------
-
--- enable awesome translaction support so we can use loc() wherever we want
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-
-------------------
--- Got Variables?
-------------------
-
-local roundLimit = 3
-local roundNumber = 0
-local firstClan = 10
-
-local versionNo = loc("v.06")
-
---------------------------
--- hog and team tracking variales
---------------------------
-
-local numhhs = 0 -- store number of hedgehogs
-local hhs = {} -- store hedgehog gears
-
-local numTeams --  store the number of teams in the game
-local teamNameArr = {}	-- store the list of teams
-local teamClan = {}
-local teamSize = {}	-- store how many hogs per team
-local teamIndex = {} -- at what point in the hhs{} does each team begin
-
-local teamComment = {}
-local teamScore = {}
-
----------
--- tumbler stuff
----------
-
-local moveTimer = 0
-local leftOn = false
-local rightOn = false
-local upOn = false
-local downOn = false
-
-local shotsMax = 30	--10
-local shotsLeft = 10
-
-local TimeLeftCounter = 0
-local TimeLeft = 60
-local stopMovement = false
-local tumbleStarted = false
-
--------
--- racer vars
---------
-
-local boosterOn = false
-local boosterFuel = 75
-local boosterPower = 0.3
-local boosterTimer = 0
-
-local bestClan = nil
-local bestTime = nil
-
-local gameBegun = false
-local gameOver = false
-local racerActive = false
-local trackTime = 0
-local wpCheckCounter = 0
-
-local wpCirc = {}
-local wpX = {}
-local wpY = {}
-local wpCol = {}
-local wpActive = {}
-local wpRad = 75
-local wpCount = 0
-local wpLimit = 20
-
--------------------
--- general methods
--------------------
-
-function RebuildTeamInfo()
-
-
-	-- make a list of individual team names
-	for i = 0, 7 do
-		teamNameArr[i] = " " -- = i
-		teamSize[i] = 0
-		teamIndex[i] = 0
-		teamScore[i] = 100000
-	end
-	numTeams = 0
-
-	for i = 0, (numhhs-1) do
-
-		z = 0
-		unfinished = true
-		while(unfinished == true) do
-
-			newTeam = true
-			tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
-
-			if tempHogTeamName == teamNameArr[z] then
-				newTeam = false
-				unfinished = false
-			end
-
-			z = z + 1
-
-			if z == TeamsCount then
-				unfinished = false
-				if newTeam == true then
-					teamNameArr[numTeams] = tempHogTeamName
-					numTeams = numTeams + 1
-				end
-			end
-
-		end
-
-	end
-
-	-- find out how many hogs per team, and the index of the first hog in hhs
-	for i = 0, (numTeams-1) do
-		for z = 0, (numhhs-1) do
-			if GetHogTeamName(hhs[z]) == teamNameArr[i] then
-				teamClan[i] = GetHogClan(hhs[z])
-				if teamSize[i] == 0 then
-					teamIndex[i] = z -- should give starting index
-				end
-				teamSize[i] = teamSize[i] + 1
-				--add a pointer so this hog appears at i in hhs
-			end
-		end
-
-	end
-
-end
-
-
------------------
--- RACER METHODS
------------------
-
-function GetSpeed()
-
-	dx, dy = GetGearVelocity(CurrentHedgehog)
-
-	x = dx*dx
-	y = dy*dy
-	z = x+y
-
-	z = z*100
-
-	k = z%1
-
-	if k ~= 0 then
-	 z = z - k
-	end
-
-	return(z)
-
-end
-
-function CheckWaypoints()
-
-	trackFinished = true
-
-	for i = 0, (wpCount-1) do
-
-		g1X, g1Y = GetGearPosition(CurrentHedgehog)
-		g2X, g2Y = wpX[i], wpY[i]
-
-		g1X = g1X - g2X
-		g1Y = g1Y - g2Y
-		dist = (g1X*g1X) + (g1Y*g1Y)
-
-		--if i == 0 then
-		--	AddCaption(dist .. "/" .. (wpRad*wpRad) )
-		--end
-
-		if dist < (wpRad*wpRad) then
-			--AddCaption("howdy")
-			wpActive[i] = true
-			wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog)) -- new				--GetClanColor(1)
-			SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 0, 10, 0, wpRad, 5, wpCol[i])
-		end
-
-		if wpActive[i] == false then
-			trackFinished = false
-		end
-
-	end
-
-	return(trackFinished)
-
-end
-
-function AdjustScores()
-
-	--[[if bestTime == nil then
-		bestTime = 100000
-		bestClan = 10
-		bestTimeComment = "N/A"
-	else
-		bestTimeComment = (bestTime/1000) ..loc("s")
-	end]]
-
-	if bestTime == nil then
-		bestTime = 100000
-		bestClan = 10
-		bestTimeComment = "N/A"
-	end
-
-	newScore = false
-
-	-- update this clan's time if the new track is better
-	for i = 0, (numTeams-1) do
-		if teamClan[i] == GetHogClan(CurrentHedgehog) then
-			if trackTime < teamScore[i] then
-				teamScore[i] = trackTime
-				newScore = true
-			else
-				newScore = false
-			end
-		end
-	end
-
-	--bestTime = 100000
-	--bestClan = 10
-
-	-- find the best time out of those so far
-	for i = 0, (numTeams-1) do
-		if teamScore[i] < bestTime then
-			bestTime = teamScore[i]
-			bestClan = teamClan[i]
-		end
-	end
-
-	if bestTime ~= 100000 then
-		bestTimeComment = (bestTime/1000) ..loc("s")
-	end
-
-	if newScore == true then
-		if trackTime == bestTime then -- best time of the race
-			ShowMission("RACER", loc("TRACK COMPLETED"), loc("NEW RACE RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. loc("WINNING TIME: ") .. bestTimeComment, 0, 4000)
-		else	-- best time for the clan
-			ShowMission("RACER", loc("TRACK COMPLETED"), loc("NEW CLAN RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. loc("WINNING TIME: ") .. bestTimeComment, 4, 4000)
-		end
-	else -- not any kind of new score
-		ShowMission("RACER", loc("TRACK COMPLETED"), loc("TIME: ") .. (trackTime/1000) ..loc("s") .. "|" .. loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
-	end
-
-end
-
-function CheckForNewRound()
-
-	if GetHogClan(CurrentHedgehog) == firstClan then
-
-		roundNumber = roundNumber + 1
-
-		for i = 0, 7 do
-				if teamNameArr[i] ~= " " then				-- teamScore[teamClan[i]]
-					teamComment[i] = teamNameArr[i] .. ": " .. (teamScore[i]/1000) .. loc("s|")
-				elseif teamNameArr[i] == " " then
-					teamComment[i] = "|"
-				end
-		end
-		ShowMission("RACER", loc("STATUS UPDATE"), loc("Rounds Complete") .. ": " .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" .. loc("Best Team Times: ") .. "|" .. teamComment[0] .. teamComment[1] .. teamComment[2] .. teamComment[3] .. teamComment[4] .. teamComment[5] .. teamComment[6] .. teamComment[7], 0, 1600)
-
-		-- end game if its at round limit
-		if roundNumber == roundLimit then
-			for i = 0, (numhhs-1) do
-				if GetHogClan(hhs[i]) ~= bestClan then
-					SetEffect(hhs[i], heResurrectable, false)
-					SetHealth(hhs[i],0)
-				end
-			end
-			gameOver = true
-			TurnTimeLeft = 1
-		end
-
-	end
-
-end
-
-function DisableTumbler()
-	stopMovement = true
-	upOn = false
-	down = false
-	leftOn = false
-	rightOn = false
-	boosterOn = false
-end
-
-----------------------------------
--- GAME METHODS / EVENT HANDLERS
-----------------------------------
-
-function onGameInit()
-	--Theme = "Hell"
-	--GameFlags
-	--GameFlags = gfDisableWind
-end
-
-
-function onGameStart()
-	RebuildTeamInfo()
-	ShowMission("RACER", "", "", 4, 4000)
-end
-
-function onHJump()
-	if (shotsLeft > 0) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then -- seems to not work with a hedgehog nil chek
-
-		shotsLeft = shotsLeft - 1
-		morte = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtShell, 0, 0, 0, 1)
-		AddCaption(loc("Shots Left: ") .. shotsLeft)
-
-
-		-- based on player movement already
-		CopyPV(CurrentHedgehog, morte) -- new addition
-
-		--x2
-		x,y = GetGearVelocity(morte)
-		x = x*2
-		y = y*2
-		SetGearVelocity(morte, x, y)
-
-		--- or based on keys?
-		--[[x = 0
-		y = 0
-
-		launchPower = 0.5
-
-		if leftOn == true then
-			x = x - launchPower
-		end
-		if rightOn == true then
-			x = x + launchPower
-		end
-
-		if upOn == true then
-			y = y - launchPower
-		end
-		if downOn == true then
-			y = y + launchPower
-		end
-
-		SetGearVelocity(morte, x, y)]]
-
-
-	end
-end
-
-function onLJump()
-
-
-	if (wpCount < wpLimit) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) and (gameBegun == false) then -- seems to not work with a hedgehog nil chek
-
-		wpX[wpCount] = GetX(CurrentHedgehog)
-		wpY[wpCount] = GetY(CurrentHedgehog)
-		wpCol[wpCount] = 0xffffffff
-		wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true)
-																		--100	  --0		--75	--wpCol[wpCount]
-		SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 20, 100, 0, 10, 0, wpRad, 5, wpCol[wpCount])
-
-		wpCount = wpCount + 1
-
-		AddCaption(loc("Waypoint placed.") .. " " .. loc("Available points remaining: ") .. (wpLimit-wpCount))
-
-		if wpCount == wpLimit then
-			AddCaption(loc("Race complexity limit reached."))
-			DisableTumbler()
-		end
-
-	end
-
-
-	if (boosterFuel > 0) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) and (gameBegun == true) then
-
-		if boosterOn == false then
-			boosterOn = true
-		else
-			boosterOn = false
-		end
-
-	end
-
-end
-
-function onLeft()
-	if (CurrentHedgehog ~= nil) and (stopMovement == false) then
-		leftOn = true
-	end
-end
-
-function onRight()
-	if (CurrentHedgehog ~= nil) and (stopMovement == false) then
-		rightOn = true
-	end
-end
-
-function onUp()
-	if (CurrentHedgehog ~= nil) and (stopMovement == false) then
-		upOn = true
-	end
-end
-
-function onDown()
-	if (CurrentHedgehog ~= nil) and (stopMovement == false) then
-		downOn = true
-	end
-end
-
-function onDownUp()
-	downOn = false
-end
-function onUpUp()
-	upOn = false
-end
-function onLeftUp()
-	leftOn = false
-end
-function onRightUp()
-	rightOn = false
-end
-
-function onNewTurn()
-
-	CheckForNewRound()
-
-	--if gameOver == false then
-		shotsLeft = shotsMax
-		stopMovement = false
-		tumbleStarted = false
-		boosterOn = false
-		boosterFuel = 75
-		SetTag(AddGear(0, 0, gtATSmoothWindCh, 0, 0, 0, 1), boosterFuel)
-		--SetInputMask(band(0xFFFFFFFF, bnot(gmAnimate+gmAttack+gmDown+gmHJump+gmLeft+gmLJump+gmPrecise+gmRight+gmSlot+gmSwitch+gmTimer+gmUp+gmWeapon)))
-		--AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
-	--end
-
-
-
-	-- Set the waypoints to unactive on new round
-	for i = 0,(wpCount-1) do
-		wpActive[i] = false
-		wpCol[i] = 0xffffffff
-		SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 0, 10, 0, wpRad, 5, wpCol[i])
-	end
-
-	-- Handle Starting Stage of Game
-	if (gameOver == false) and (gameBegun == false) then
-		if wpCount >= 3 then
-			gameBegun = true
-			racerActive = true
-			roundNumber = 0 -- 0
-			firstClan = GetHogClan(CurrentHedgehog)
-			ShowMission("RACER", loc("GAME BEGUN!!!"), loc("Complete the track as fast as you can!"), 2, 4000)
-		else
-			ShowMission("RACER", loc("NOT ENOUGH WAYPOINTS"), loc("Place more waypoints using [ENTER]"), 2, 4000)
-		end
-	end
-
-	if gameOver == true then
-		gameBegun = false
-		stopMovement = true
-		tumbleStarted = false
-	end
-
-end
-
-function onGameTick()
-
-	-- start the player tumbling with a boom once their turn has actually begun
-	if tumbleStarted == false then
-		if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
-			AddCaption("Good to go!")
-			tumbleStarted = true
-			racerActive = true
-			trackTime = 0
-			TimeLeft = 60
-
-			-- if the gamehas started put the player in the middle of the first
-			--waypoint that was placed
-			if gameBegun == true then
-				SetGearPosition(CurrentHedgehog, wpX[0], wpY[0])
-				AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
-				FollowGear(CurrentHedgehog)
-			else -- otherwise just start him tumbling from wherever he is
-				AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
-			end
-
-		end
-	end
-
-	-- has the player started his tumbling spree?
-	if (CurrentHedgehog ~= nil) and (tumbleStarted == true) then
-
-		--AddCaption(LOC_NOT("Speed: ") .. GetSpeed())
-
-		-- if the RACE has started, show tracktimes and keep tabs on waypoints
-		if (racerActive == true) and (gameBegun == true) then
-
-			trackTime = trackTime + 1
-
-			wpCheckCounter = wpCheckCounter + 1
-			if (wpCheckCounter == 100) then
-
-				AddCaption(loc("Track Time: ") .. (trackTime/1000) .. loc("s") )
-				wpCheckCounter = 0
-				if (CheckWaypoints() == true) then
-					AdjustScores()
-					racerActive = false
-					DisableTumbler()
-				end
-
-			end
-
-		end
-
-		if boosterOn == true then
-			boosterTimer = boosterTimer + 1
-			if boosterTimer == 150 then --200
-				boosterTimer = 0
-				boosterFuel = boosterFuel - 1
-				SetTag(AddGear(0, 0, gtATSmoothWindCh, 0, 0, 0, 1), boosterFuel)
-				if boosterFuel == 0 then
-					boosterOn = false
-				end
-			end
-		end
-
-		-- Calculate and display turn time
-		TimeLeftCounter = TimeLeftCounter + 1
-		if TimeLeftCounter == 1000 then
-			TimeLeftCounter = 0
-			TimeLeft = TimeLeft - 1
-
-			if TimeLeft >= 0 then
-				--TurnTimeLeft = TimeLeft
-				--AddCaption(LOC_NOT("Time Left: ") .. TimeLeft)
-			end
-
-		end
-
-		-- if the player has expended his tunbling time, stop him tumbling
-		if TimeLeft == 0 then
-			DisableTumbler()
-		end
-
-
-		-- handle movement based on IO
-		moveTimer = moveTimer + 1
-		if moveTimer == 100 then -- 100
-			moveTimer = 0
-
-			-- keep in mind gravity is acting on the hog
-			-- so his down is more powerful than his up
-
-			dx, dy = GetGearVelocity(CurrentHedgehog)
-
-			dxlimit = 0.4 --0.4
-			dylimit = 0.4 --0.4
-
-			if boosterOn == true then
-
-				--flame trail, now removed
-				AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtFlame, 0, 0, 0, 0)
-				--tempE = AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtDust, 0, false)
-
-				dxlimit = dxlimit + boosterPower
-				dylimit = dylimit + boosterPower
-			else
-				tempE = AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtDust, 0, false)
-				g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
-				SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, GetClanColor(GetHogClan(CurrentHedgehog)) )
-			end
-
-			if dx > dxlimit then
-				dx = dxlimit
-			end
-			if dy > dylimit then
-				dy = dylimit
-			end
-			if dx < -dxlimit then
-				dx = -dxlimit
-			end
-			if dy < -dylimit then
-				dy = -dylimit
-			end
-
-
-			dxPower = 0.1 --0.1
-			dyPower = 0.1 --0.1
-
-			if leftOn == true then
-				dx = dx - dxPower
-			end
-			if rightOn == true then
-				dx = dx + dxPower
-			end
-
-			if upOn == true then
-				dy = dy - dyPower -- -0.1 -- new addition
-			end
-			if downOn == true then
-				dy = dy + dyPower
-			end
-
-			--if leftOn == true then
-			--	dx = dx - 0.04
-			--end
-			--if rightOn == true then
-			--	dx = dx + 0.04
-			--end
-
-			--if upOn == true then
-			--	dy = dy - 0.1
-			--end
-			--if downOn == true then
-			--	dy = dy + 0.06
-			--end
-
-			SetGearVelocity(CurrentHedgehog, dx, dy)
-
-		end
-
-	end
-
-end
-
-function onGearDamage(gear, damage)
-	--if gear == CurrentHedgehog then
-		-- You are now tumbling
-	--end
-end
-
-function onGearResurrect(gear)
-
-	AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
-
-	-- if the player stops and "dies" or flies into water, stop him tumbling
-	if gear == CurrentHedgehog then
-		DisableTumbler()
-	end
-
-end
-
-function onGearAdd(gear)
-
-	if GetGearType(gear) == gtHedgehog then
-		hhs[numhhs] = gear
-		numhhs = numhhs + 1
-		SetEffect(gear, heResurrectable, true)
-	end
-
-end
-
-function onGearDelete(gear)
-	--not needed today, yet
-
-	--sticky camera
-	if CurrentHedgehog ~= nil then
-		FollowGear(CurrentHedgehog)
-	end
-
-end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.cfg	Sun Sep 11 04:08:50 2011 +0200
@@ -0,0 +1,2 @@
+Default
+Default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua	Sun Sep 11 04:08:50 2011 +0200
@@ -0,0 +1,596 @@
+
+------------------------------------------
+-- RACER 0.1
+-- map-independant racing script
+-- by mikade
+-----------------------------------------
+
+-----------------------------------
+--0.1: took all the code from crazy racer and scrapped most of it
+-----------------------------------
+
+-- Removed tumbler system
+-- Removed extra adds like boosters etc
+-- Added experimental waypoint placement system
+-- More user feedback
+-- Reduced race complexity limit to 5 waypoints
+-- stop placement at complexity limit reached and end turn
+-- guys dont keep racing after dying
+-- invulnerable feasibility
+-- reverted time keeping method
+-- reduced feedback display time
+-- colour-coded addcaptions
+-- cleaned up code
+-- support for more players properly added
+-- tardis fix
+-- remove airstrikes
+
+-- i think the remainder 0 .456 sec of the tracktime isnt getting reset on newturn
+
+-- update feedback
+
+-----------------------------
+-- SCRIPT BEGINS
+-----------------------------
+
+loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+
+------------------
+-- Got Variables?
+------------------
+
+local fMod = 1000000 -- 1
+local roundLimit = 3
+local roundNumber = 0
+local firstClan = 10
+
+local fastX = {}
+local fastY = {}
+local fastCount = 0
+local fastIndex = 0
+local fastColour
+
+local currX = {}
+local currY = {}
+local currCount = 0
+
+--------------------------
+-- hog and team tracking variales
+--------------------------
+
+local numhhs = 0 -- store number of hedgehogs
+local hhs = {} -- store hedgehog gears
+
+local numTeams --  store the number of teams in the game
+local teamNameArr = {}	-- store the list of teams
+local teamClan = {}
+local teamSize = {}	-- store how many hogs per team
+local teamIndex = {} -- at what point in the hhs{} does each team begin
+
+local teamComment = {}
+local teamScore = {}
+
+-------
+-- racer vars
+--------
+
+local cGear = nil
+local gTimer = 0
+
+local bestClan = nil
+local bestTime = nil
+
+local gameBegun = false
+local gameOver = false
+local racerActive = false
+local trackTime = 0
+local wpCheckCounter = 0
+
+local wpCirc = {}
+local wpX = {}
+local wpY = {}
+local wpCol = {}
+local wpActive = {}
+local wpRad = 450 --75 
+local wpCount = 0
+local wpLimit = 5
+
+-------------------
+-- general methods
+-------------------
+
+function RebuildTeamInfo()
+
+
+	-- make a list of individual team names
+	for i = 0, (TeamsCount-1) do
+		teamNameArr[i] = " " -- = i
+		teamSize[i] = 0
+		teamIndex[i] = 0
+		teamScore[i] = 100000
+	end
+	numTeams = 0
+
+	for i = 0, (numhhs-1) do
+
+		z = 0
+		unfinished = true
+		while(unfinished == true) do
+
+			newTeam = true
+			tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
+
+			if tempHogTeamName == teamNameArr[z] then
+				newTeam = false
+				unfinished = false
+			end
+
+			z = z + 1
+
+			if z == TeamsCount then
+				unfinished = false
+				if newTeam == true then
+					teamNameArr[numTeams] = tempHogTeamName
+					numTeams = numTeams + 1
+				end
+			end
+
+		end
+
+	end
+
+	-- find out how many hogs per team, and the index of the first hog in hhs
+	for i = 0, (numTeams-1) do
+		for z = 0, (numhhs-1) do
+			if GetHogTeamName(hhs[z]) == teamNameArr[i] then
+				teamClan[i] = GetHogClan(hhs[z])
+				if teamSize[i] == 0 then
+					teamIndex[i] = z -- should give starting index
+				end
+				teamSize[i] = teamSize[i] + 1
+				--add a pointer so this hog appears at i in hhs
+			end
+		end
+
+	end
+
+end
+
+
+-----------------
+-- RACER METHODS
+-----------------
+
+function CheckWaypoints()
+
+	trackFinished = true
+	
+	for i = 0, (wpCount-1) do
+
+		g1X, g1Y = GetGearPosition(CurrentHedgehog)
+		g2X, g2Y = wpX[i], wpY[i]
+
+		g1X = g1X - g2X
+		g1Y = g1Y - g2Y
+		dist = (g1X*g1X) + (g1Y*g1Y)
+
+		--if i == 0 then
+		--	AddCaption(dist .. "/" .. (wpRad*wpRad) )
+		--end
+
+		NR = (48/100*wpRad)/2		
+
+		if dist < (NR*NR) then		
+		--if dist < (wpRad*wpRad) then
+			--AddCaption("howdy")
+			wpActive[i] = true
+			wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog)) -- new				--GetClanColor(1)
+			SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
+
+			wpRem = 0
+			for k = 0, (wpCount-1) do
+				if wpActive[k] == false then
+					wpRem = wpRem + 1				
+				end
+			end
+
+			AddCaption(loc("Way-Points Remaining") .. ": " .. wpRem,0xffba00ff,capgrpAmmoinfo)
+
+		end
+
+		if wpActive[i] == false then
+			trackFinished = false
+		end
+
+	end
+
+	return(trackFinished)
+
+end
+
+function AdjustScores()
+
+	if bestTime == nil then
+		bestTime = 100000
+		bestClan = 10
+		bestTimeComment = "N/A"
+	end
+
+	newScore = false
+
+	-- update this clan's time if the new track is better
+	for i = 0, (numTeams-1) do
+		if teamClan[i] == GetHogClan(CurrentHedgehog) then
+			if trackTime < teamScore[i] then
+				teamScore[i] = trackTime
+				newScore = true
+			else
+				newScore = false
+			end
+		end
+	end
+
+	--bestTime = 100000
+	--bestClan = 10
+
+	-- find the best time out of those so far
+	for i = 0, (numTeams-1) do
+		if teamScore[i] < bestTime then
+			bestTime = teamScore[i]
+			bestClan = teamClan[i]
+		end
+	end
+
+	if bestTime ~= 100000 then
+		bestTimeComment = (bestTime/1000) ..loc("s")
+	end
+
+	if newScore == true then
+		if trackTime == bestTime then -- best time of the race
+			ShowMission(loc("RACER"), 
+			loc("TRACK COMPLETED"), 
+			loc("NEW RACE RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. 
+			loc("WINNING TIME: ") .. bestTimeComment, 0, 4000)
+		else	-- best time for the clan
+			ShowMission(loc("RACER"), 
+			loc("TRACK COMPLETED"), 
+			loc("NEW CLAN RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. 
+			loc("WINNING TIME: ") .. bestTimeComment, 4, 4000)
+		end
+	else -- not any kind of new score
+		ShowMission(loc("RACER"), 
+		loc("TRACK COMPLETED"), 
+		loc("TIME: ") .. (trackTime/1000) ..loc("s") .. "|" .. 
+		loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
+	end
+
+
+	--------
+	--new
+	--------
+
+	if bestTime == trackTime then
+		--AddCaption("wooooooooooooooooooooooooooooo")
+
+		fastColour = GetClanColor(GetHogClan(CurrentHedgehog))
+
+		for i = 0, (currCount-1) do
+			fastX[i] = currX[i]
+			fastY[i] = currY[i]
+		end
+
+		fastCount = currCount
+		fastIndex = 0
+
+		--currCount = 0 -- is this needed?
+
+	else
+		currCount = 0
+		fastIndex = 0
+	end
+
+
+end
+
+function CheckForNewRound()
+
+	if GetHogClan(CurrentHedgehog) == firstClan then
+
+		roundNumber = roundNumber + 1
+
+		totalComment = ""		
+		for i = 0, (TeamsCount-1) do
+				if teamNameArr[i] ~= " " then				-- teamScore[teamClan[i]]
+					teamComment[i] = teamNameArr[i] .. ": " .. (teamScore[i]/1000) .. loc("s|")
+					totalComment = totalComment .. teamComment[i]
+				elseif teamNameArr[i] == " " then
+					teamComment[i] = "|"
+				end
+		end
+
+		ShowMission(	loc("RACER"), 
+				loc("STATUS UPDATE"), 
+				loc("Rounds Complete: ") .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" .. 
+				loc("Best Team Times: ") .. "|" .. totalComment, 0, 4000)
+
+		-- end game if its at round limit
+		if roundNumber == roundLimit then
+			for i = 0, (numhhs-1) do
+				if GetHogClan(hhs[i]) ~= bestClan then
+					SetEffect(hhs[i], heResurrectable, false)
+					SetHealth(hhs[i],0)
+				end
+			end
+			gameOver = true
+			TurnTimeLeft = 1
+		end
+
+	end
+
+end
+
+function DisableTumbler()
+	currCount = 0
+	fastIndex = 0
+	TurnTimeLeft = 0
+	racerActive = false -- newadd
+end
+
+function HandleGhost()
+
+	-- get the current xy of the racer at this point
+	currX[currCount] = GetX(CurrentHedgehog)
+	currY[currCount] = GetY(CurrentHedgehog)
+	currCount = currCount + 1
+
+	-- draw a ping of smoke where the fastest player was at this point
+	if (fastCount ~= 0) and (fastIndex < fastCount) then
+
+		fastIndex = fastIndex + 1
+
+		tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false)
+		g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
+		SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour )
+
+		--AddCaption("fC: " .. fastIndex .. " / " .. fastCount)
+
+	else
+
+		--AddCaption("excep fC: " .. fastIndex .. " / " .. fastCount)
+
+	end
+
+
+
+end
+
+----------------------------------
+-- GAME METHODS / EVENT HANDLERS
+----------------------------------
+
+function onGameInit()
+	GameFlags = gfInfAttack + gfSolidLand + gfInvulnerable
+	CaseFreq = 0
+	Delay = 1000 -- doh
+end
+
+
+function onGameStart()
+	RebuildTeamInfo()
+
+	ShowMission	(
+				loc("RACER"),
+				loc("a Hedgewars mini-game"),
+				
+				loc("Build a track and race.") .. "|" ..
+				loc("Round Limit:") .. " " .. roundLimit .. "|" ..
+								
+				"", 4, 4000
+				)
+
+
+end
+
+function PlaceWayPoint(x,y)
+
+	if (wpCount < wpLimit) then -- seems to not work with a hedgehog nil chek
+
+		wpX[wpCount] = x
+		wpY[wpCount] = y
+		wpCol[wpCount] = 0xffffffff
+		wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true)
+																		--100	  
+		SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 20, 100, 1, 10, 0, wpRad, 5, wpCol[wpCount])
+
+		wpCount = wpCount + 1
+
+		AddCaption(loc("Waypoint placed.") .. " " .. loc("Available points remaining: ") .. (wpLimit-wpCount))
+
+		-- for some reason the code doesnt function if placed here		
+		--[[if wpCount == wpLimit then
+			AddCaption(loc("Race complexity limit reached."))
+			--DisableTumbler()
+		end]]
+
+	end
+
+end
+
+function onNewTurn()
+
+	CheckForNewRound()
+
+	racerActive = false
+	
+	trackTime = 0
+
+	currCount = 0 -- hopefully this solves problem
+	AddAmmo(CurrentHedgehog, amAirAttack, 0)
+	gTimer = 0
+
+	-- Set the waypoints to unactive on new round
+	for i = 0,(wpCount-1) do
+		wpActive[i] = false
+		wpCol[i] = 0xffffffff
+		SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
+	end
+
+	-- Handle Starting Stage of Game
+	if (gameOver == false) and (gameBegun == false) then
+		if wpCount >= 3 then
+			gameBegun = true
+			roundNumber = 0 
+			firstClan = GetHogClan(CurrentHedgehog)
+			ShowMission(loc("RACER"), 
+			loc("GAME BEGUN!!!"), 
+			loc("Complete the track as fast as you can!"), 2, 4000)
+		else
+			ShowMission(loc("RACER"), 
+			loc("NOT ENOUGH WAYPOINTS"), 
+			loc("Place more waypoints using the 'Air Attack' weapon."), 2, 4000)
+			AddAmmo(CurrentHedgehog, amAirAttack, 4000)
+		end
+	end
+
+	if gameOver == true then
+		gameBegun = false
+		racerActive = false -- newadd
+	end
+
+	AddAmmo(CurrentHedgehog, amTardis, 0)
+
+end
+
+function onGameTick()
+
+	-- convert airstrikes into waypoints
+	if cGear ~= nil then
+		x,y = GetGearTarget(cGear)
+		PlaceWayPoint(x, y)
+		DeleteGear(cGear)
+		if wpCount == wpLimit then
+			AddCaption(loc("Race complexity limit reached."))
+			DisableTumbler()
+		end
+	end
+
+
+
+	-- start the player tumbling with a boom once their turn has actually begun
+	if racerActive == false then
+
+		if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
+			
+			-- if the gamehas started put the player in the middle of the first
+			--waypoint that was placed
+			if gameBegun == true then
+
+				AddCaption(loc("Good to go!"))
+				racerActive = true
+				trackTime = 0
+				
+				SetGearPosition(CurrentHedgehog, wpX[0], wpY[0])
+				AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
+				FollowGear(CurrentHedgehog)
+				ShowMission("...", "...", "...", 2, 1)
+				
+			else 
+				-- still in placement mode
+			end
+
+		end
+	end
+
+
+
+	-- has the player started his tumbling spree?
+	if (CurrentHedgehog ~= nil) then
+
+		--airstrike conversion used to be here
+
+		-- if the RACE has started, show tracktimes and keep tabs on waypoints
+		if (racerActive == true) and (gameBegun == true) then 
+
+			--ghost			
+			gTimer = gTimer + 1
+			if gTimer == 15 then
+				gTimer = 0
+				HandleGhost()
+			end
+
+			trackTime = trackTime + 1
+			
+			wpCheckCounter = wpCheckCounter + 1
+			if (wpCheckCounter == 100) then
+			
+				wpCheckCounter = 0
+				AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+				
+				if (CheckWaypoints() == true) then
+					AdjustScores()
+					racerActive = false
+					DisableTumbler()
+				end
+				
+			end
+
+		end
+
+		
+
+		-- if the player has expended his tunbling time, stop him tumbling
+		if TurnTimeLeft <= 1 then
+			DisableTumbler()
+		end
+
+	end
+
+end
+
+function onGearResurrect(gear)
+
+	AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+
+	-- if the player stops and "dies" or flies into water, stop him racing
+	if gear == CurrentHedgehog then
+		DisableTumbler()
+		ShowMission(loc("RACER"), 
+		loc("TRACK FAILED!"), 
+		loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
+	end
+
+end
+
+function onGearAdd(gear)
+
+	if GetGearType(gear) == gtHedgehog then
+		hhs[numhhs] = gear
+		numhhs = numhhs + 1
+		SetEffect(gear, heResurrectable, true)
+	end
+
+	if GetGearType(gear) == gtAirAttack then
+		cGear = gear		
+	end
+
+end
+
+function onGearDelete(gear)
+
+	if CurrentHedgehog ~= nil then
+		FollowGear(CurrentHedgehog)
+	end
+
+	if GetGearType(gear) == gtAirAttack then
+		cGear = nil		
+	end
+
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amRope, 9, 0, 0, 0)	
+	SetAmmo(amJetpack, 9, 0, 0, 0)	
+	SetAmmo(amSkip, 9, 0, 0, 0)
+end
+
+