Make wider range of numbers representable with FPNum on the cost of smaller precision
-------------
-- CONTROL --
-------------
-- Goal: Stand on pillars to score points over time.
-- First clan to hit the score limit wins!
-- Rules:
-- * Each pillar you control generates 1 point every 2 seconds.
-- * If multiple clans compete for a pillar, no one generates points for this pillar.
-- * If you skip turn, you win the same points as if you would have just waited out the turn
-- * Hogs get revived.
-----------------
-- script begins
-----------------
HedgewarsScriptLoad("/Scripts/Locale.lua")
---------------------------------------------------------------
-- lots variables and things
---------------------------------------------------------------
local TimeCounter = 0
local gameWon = false
local pointLimit = 300
local missionName = loc("Control")
local missionCaption = loc("Domination game")
local missionHelp
local vCirc = {}
local vCircCount = 0
--local hGCount = 0
local vCircX = {}
local vCircY = {}
local vCircMinA = {}
local vCircMaxA = {}
local vCircType = {}
local vCircPulse = {}
local vCircFuckAll = {}
local vCircRadius = {}
local vCircWidth = {}
local vCircCol = {}
--------------------------
-- hog and team tracking variales
--------------------------
local numhhs = 0 -- store number of hedgehogs
local hhs = {} -- store hedgehog gears
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 = {}
--------------------------------
--zone and teleporter variables
--------------------------------
local cPoint = {}
local cOwnerClan = {}
local zXMin = {}
local zWidth = {}
local zYMin = {}
local zHeight = {}
local zOccupied = {}
local zCount = 0
------------------------
-- zone methods
------------------------
-- see on gameTick also
function CreateZone(xMin, yMin, width, height)
zXMin[zCount] = xMin
zYMin[zCount] = yMin
zWidth[zCount] = width
zHeight[zCount] = height
zOccupied[zCount] = false
zCount = zCount + 1
return (zCount-1)
end
function GearIsInZone(gear, zI)
if (GetX(gear) > zXMin[zI]) and (GetX(gear) < (zXMin[zI]+zWidth[zI])) and (GetY(gear) > zYMin[zI]) and (GetY(gear) < (zYMin[zI]+zHeight[zI])) then
zOccupied[zI] = true
else
zOccupied[zI] = false
end
return zOccupied[zI]
end
function ZonesAreEmpty()
okay = true
for i = 0,(zCount-1) do
for k = 0, (numhhs-1) do
if (hhs[k] ~= nil) then
if (GearIsInZone(hhs[k],i)) == true then
FindPlace(hhs[k], false, 0, LAND_WIDTH, true)
okay = false
end
end
end
end
return(okay)
end
function CheckZones()
for i = 0,(zCount-1) do
SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], vCircMinA[i], vCircMaxA[i], vCircType[i], vCircPulse[i], vCircFuckAll[i], vCircRadius[i], vCircWidth[i], 0xffffffff)
cOwnerClan[i] = nil
for k = 0, (numhhs-1) do
if (hhs[k] ~= nil) then
if (GearIsInZone(hhs[k],i)) == true then
if cOwnerClan[i] ~= nil then
if cOwnerClan[i] ~= GetHogClan(hhs[k]) then
--if the hog now being compared is different to one that is also here and was previously compared
SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], vCircMinA[i], vCircMaxA[i], vCircType[i], vCircPulse[i], vCircFuckAll[i], vCircRadius[i], vCircWidth[i], 0xffffffff)
cOwnerClan[i] = 10 -- this means conflicted
end
elseif cOwnerClan[i] == nil then
cOwnerClan[i] = GetHogClan(hhs[k])
SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], vCircMinA[i], vCircMaxA[i], vCircType[i], vCircPulse[i], vCircFuckAll[i], vCircRadius[i], vCircWidth[i], GetClanColor( GetHogClan(hhs[k])))
end
end
end
end
end
end
function AwardPoints()
for i = 0,(zCount-1) do
-- give score to all players controlling points
-- only give score to the player currently in control
if CurrentHedgehog ~= nil then
if cOwnerClan[i] == GetHogClan(CurrentHedgehog) then
teamScore[cOwnerClan[i]] = teamScore[cOwnerClan[i]] + 1
end
end
end
-- i want to show all the tags at once as having the SAME score not 1,2,3,4 so alas, repeating the loop seems needed
for i = 0,(zCount-1) do
if CurrentHedgehog ~= nil then
if cOwnerClan[i] == GetHogClan(CurrentHedgehog) then
local g = AddVisualGear(vCircX[i], vCircY[i]-100, vgtHealthTag, 100, false)
SetVisualGearValues(g, vCircX[i], vCircY[i]-100, 0, 0, 0, 0, 0, teamScore[cOwnerClan[i]], 1500, GetClanColor(cOwnerClan[i]))
end
end
end
-- Update team labels and graph
local clanGraphPointWritten = {}
for i = 0,(TeamsCount-1) do
if teamNameArr[i] ~= " " then
SetTeamLabel(teamNameArr[i], teamScore[teamClan[i]])
if not clanGraphPointWritten[teamClan[i]] then
SendStat(siClanHealth, teamScore[teamClan[i]], teamNameArr[i])
clanGraphPointWritten[teamClan[i]] = true
end
end
end
end
-----------------
-- 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] = 0
end
local 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, TeamsCount-1 do
SetTeamLabel(GetTeamName(i), "0")
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
------------------------
-- game methods
------------------------
function onSkipTurn()
if CurrentHedgehog ~= nil then
z = (TurnTimeLeft / 2000) - (TurnTimeLeft / 2000)%2
for i = 0, z do
AwardPoints()
end
end
end
function onGameInit()
-- Things we don't modify here will use their default values.
EnableGameFlags(gfInfAttack, gfSolidLand)
DisableGameFlags(gfKing, gfAISurvival)
WaterRise = 0
HealthDecrease = 0
SendHealthStatsOff()
SendRankingStatsOff()
end
function onGameStart()
-- build zones
cPoint[0] = CreateZone(571,47,120,80)
cPoint[1] = CreateZone(1029,643,120,80)
cPoint[2] = CreateZone(322,1524,120,80)
cPoint[3] = CreateZone(1883,38,120,80)
cPoint[4] = CreateZone(3821,46,120,80)
cPoint[5] = CreateZone(2679,1338,120,80)
vCircX[0], vCircY[0] = 631, 82
vCircX[1], vCircY[1] = 1088, 684
vCircX[2], vCircY[2] = 381, 1569
vCircX[3], vCircY[3] = 1942, 77
vCircX[4], vCircY[4] = 3883, 89
vCircX[5], vCircY[5] = 2739, 1378
for i = 0, 5 do
vCirc[i] = AddVisualGear(0,0,vgtCircle,0,true)
vCircMinA[i] = 20
vCircMaxA[i] = 255
vCircType[i] = 1
vCircPulse[i] = 10
vCircFuckAll[i] = 0
vCircRadius[i] = 300
vCircWidth[i] = 5
vCircCol[i] = 0xffffffff
SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], vCircMinA[i], vCircMaxA[i], vCircType[i], vCircPulse[i], vCircFuckAll[i], vCircRadius[i], vCircWidth[i], vCircCol[i])
end
--new improved placement schematics aw yeah
RebuildTeamInfo()
for i = 0, ClansCount - 1 do
pointLimit = pointLimit - 25
end
missionHelp = loc("Control pillars to score points.") .. "|" ..
loc("Hedgehogs will be revived after their death.") .. "|" ..
string.format(loc("Score goal: %d"), pointLimit)
-- reposition hogs if they are on control points until they are not or sanity limit kicks in
reN = 0
while (reN < 10) do
if ZonesAreEmpty() == false then
reN = reN + 1
else
reN = 15
end
end
for h=0, numhhs-1 do
-- Tardis screws up the game too much, teams might not get killed correctly after victory
-- if a hog is still in time-travel.
-- This could be fixed, removing the Tardis is just a simple and lazy fix.
AddAmmo(hhs[h], amTardis, 0)
-- Resurrector is pointless, all hogs are already automatically resurrected.
AddAmmo(hhs[h], amResurrector, 0)
-- Remove suicidal weapons as they might wipe out the team
AddAmmo(hhs[h], amKamikaze, 0)
AddAmmo(hhs[h], amPiano, 0)
end
ShowMission(missionName, missionCaption, missionHelp, 0, 0)
end
local RankTeams = function(teamList)
local teamRank = function(a, b)
if a.score ~= b.score then
return a.score > b.score
else
return a.clan > b.clan
end
end
table.sort(teamList, teamRank)
local rank, plusRank, score, clan
for i=1, #teamList do
if i == 1 then
rank = 1
plusRank = 1
score = teamList[i].score
clan = teamList[i].clan
end
if (teamList[i].score < score) then
rank = rank + plusRank
plusRank = 1
end
if (teamList[i].score == score and teamList[i].clan ~= clan) then
plusRank = plusRank + 1
end
teamList[i].rank = rank
score = teamList[i].score
clan = teamList[i].clan
end
for i=1, #teamList do
SendStat(siPointType, "!POINTS")
SendStat(siTeamRank, tostring(teamList[i].rank))
SendStat(siPlayerKills, tostring(teamList[i].score), teamList[i].name)
end
end
function onNewTurn()
-- reset the time counter so that it will get set to TurnTimeLeft in onGameTick
TimeCounter = 0
if lastTeam ~= GetHogTeamName(CurrentHedgehog) then
lastTeam = GetHogTeamName(CurrentHedgehog)
end
if gameWon == false then
for i = 0, TeamsCount - 1 do
if teamScore[i] >= pointLimit then --150
gameWon = true
winnerClan = i
end
end
if gameWon == true then
for i = 0, (numhhs-1) do
if hhs[i] ~= nil then
if GetHogClan(hhs[i]) ~= winnerClan then
SetEffect(hhs[i], heResurrectable, 0)
SetHealth(hhs[i],0)
end
end
end
EndTurn(true)
-- Rankings
local teamList = {}
for i=0, TeamsCount - 1 do
local name = GetTeamName(i)
local clan = GetTeamClan(name)
table.insert(teamList, { score = teamScore[teamClan[i]], name = name, clan = clan })
end
RankTeams(teamList)
SendStat(siGraphTitle, loc("Score graph"))
end
end
end
function onGameTick()
vCircCount = vCircCount + 1
if (vCircCount >= 500) and (gameWon == false) then
vCircCount = 0
CheckZones()
end
-- set TimeCounter to starting time if it is uninitialised (from onNewTurn)
if (TimeCounter == 0) and (TurnTimeLeft > 0) then
TimeCounter = TurnTimeLeft
end
-- has it ACTUALLY been 2 seconds since we last did this?
if (TimeCounter - TurnTimeLeft) >= 2000 then
TimeCounter = TurnTimeLeft
if (gameWon == false) then
AwardPoints()
end
end
end
function onHogAttack(ammoType)
-- Update TimeCounter after using extra time
if ammoType == amExtraTime then
if (TimeCounter == 0) and (TurnTimeLeft > 0) then
TimeCounter = TurnTimeLeft
end
TimeCounter = TimeCounter + 30000
end
end
function InABetterPlaceNow(gear)
for i = 0, (numhhs-1) do
if gear == hhs[i] then
hhs[i] = nil
end
end
end
function onGearAdd(gear)
if GetGearType(gear) == gtHedgehog then
hhs[numhhs] = gear
numhhs = numhhs + 1
SetEffect(gear, heResurrectable, 1)
end
end
function onGearDelete(gear)
if GetGearType(gear) == gtHedgehog then
InABetterPlaceNow(gear)
end
end