diff -r f5d858e4b634 -r 63aafc9c2a81 share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua Fri Dec 24 00:53:50 2010 -0500 @@ -0,0 +1,597 @@ +-------------------------------- +-- CAPTURE_THE_FLAG_CUSTOM 0.3 +-- by mikade +-------------------------------- + +-- Version History +--------- +-- 0.1 +--------- + +-- [conversion from map-dependant CTF_Blizzard to map independant Capture the Flag] +-- added an intial starting stage where flagspawn is decided by the players (weapon set will require a jetpack unless I set) +-- changed the flag from a crate to a visual gear, and all associated methods and checks relating to flags (five hours later, lol) +-- changed starting/respawning positioning to accommodate different map sizes +-- added another circle to mark flag spawn +-- added gameFlag filter +-- changed scoring feedback +-- cleaned up some code + +-- removing own flag from spawning point no longer possible +-- destroying flags no longer possible. +-- added basic glowing circle effect to spawn area +-- added expanding circle to fgear itself + +-- removed teleporters +-- removed random crate drops (this should be decided by scheme) +-- removed set map criteria like minesNum, turnTime, explosives etc. except for sudden death +-- removed weapon defintions +-- removed placement and respawning methods, hopefully divideTeams will have this covered + +--------- +-- 0.2 +--------- + +-- [now with user friendliness] +-- flag is now placed wherever you end up at the end of your first turn, this ensures that it is always placed by turn 3 +-- removed a bunch of backup code and no-longer needed variables / methods from CTF_Blizzard days +-- removed an aura that was still mistakenly hanging about +-- added an in-game note about placements +-- added an in-game note about the rules of the game +-- added translation support and loc()'ed everything +-- changed things so the seed is no longer always the same... + +-- In this version: +--------- +-- 0.3 +--------- +-- [fufufufu kamikaze fix] +-- added nill checks to make sure the player doesn't generate errors by producing a nil value in hhs[] when he uses kamikaze +-- added a check to make sure the player doesn't kamikaze straight down and make the flag's starting point underwater +-- added a check to make sure the player drops the flag if he has it and he uses kamikaze + +----------------- +--SCRIPT BEGINS +----------------- + +-- enable awesome translaction support so we can use loc() wherever we want +loadfile(GetDataPath() .. "Scripts/Locale.lua")() + +--------------------------------------------------------------- +----------lots of bad variables and things +----------because someone is too lazy +----------to read about tables properly +------------------ "Oh well, they probably have the memory" + +local gameStarted = false +local gameTurns = 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 teamSize = {} -- store how many hogs per team +local teamIndex = {} -- at what point in the hhs{} does each team begin + +------------------- +-- flag variables +------------------- + +local fPlaced = {} -- has the flag been placed TRUE/FALSE + +local fGear = {} -- pointer to the visual gears that represent the flag +local fGearX = {} +local fGearY = {} + +local fThief = {} -- pointer to the hogs who stole the flags +local fIsMissing = {} -- have the flags been destroyed or captured +local fNeedsRespawn = {} -- do the flags need to be respawned +local fCaptures = {} -- the team "scores" how many captures +local fSpawnX = {} -- spawn X for flags +local fSpawnY = {} -- spawn Y for flags + +local fThiefX = {} +local fThiefY = {} +local FTTC = 0 -- flag thief tracker counter + +local fSpawnC = {} -- spawn circle marker +local fCirc = {} -- flag/carrier marker circles +local fCol = {} -- colour of the clans + +local fGearRad = 0 +local fGearRadMin = 5 +local fGearRadMax = 33 +local fGearTimer = 0 + +------------------------ +--flag methods +------------------------ + +function CheckScore(teamID) + + if teamID == 0 then + alt = 1 + elseif teamID == 1 then + alt = 0 + end + + if fCaptures[teamID] == 3 then + for i = 0, (numhhs-1) do + if hhs[i] ~= nil then + if GetHogClan(hhs[i]) == alt then + SetEffect(hhs[i], heResurrectable, false) + SetHealth(hhs[i],0) + end + end + end + if CurrentHedgehog ~= nil then + ShowMission(loc("GAME OVER!"), loc("Victory for the ") .. GetHogTeamName(CurrentHedgehog), loc("Hooray!"), 0, 0) + end + end + +end + +function DoFlagStuff(gear) + + if (gear == fGear[0]) then + wtf = 0 + bbq = 1 + elseif (gear == fGear[1]) then + wtf = 1 + bbq = 0 + end + + -- player has successfully captured the enemy flag + if (GetHogClan(CurrentHedgehog) == wtf) and (CurrentHedgehog == fThief[bbq]) and (fIsMissing[wtf] == false) then + + DeleteVisualGear(fGear[wtf]) + fGear[wtf] = nil -- the flag has now disappeared + + fIsMissing[wtf] = false + fNeedsRespawn[wtf] = true + fIsMissing[bbq] = false + fNeedsRespawn[bbq] = true + fCaptures[wtf] = fCaptures[wtf] +1 + ShowMission(loc("You have SCORED!!"), GetHogTeamName(CurrentHedgehog) .. ": " .. fCaptures[wtf], loc("Opposing Team: ") .. fCaptures[bbq], 0, 0) + PlaySound(sndVictory) + fThief[bbq] = nil -- player no longer has the enemy flag + CheckScore(wtf) + + --if the player is returning the flag + elseif (GetHogClan(CurrentHedgehog) == wtf) and (fIsMissing[wtf] == true) then + + DeleteVisualGear(fGear[wtf]) + fGear[wtf] = nil -- the flag has now disappeared + + fNeedsRespawn[wtf] = true + HandleRespawns() -- this will set fIsMissing[wtf] to false :) + AddCaption(loc("Flag returned!")) + + --if the player is taking the enemy flag + elseif GetHogClan(CurrentHedgehog) == bbq then + + DeleteVisualGear(fGear[wtf]) + fGear[wtf] = nil -- the flag has now disappeared + + fIsMissing[wtf] = true + for i = 0,numhhs-1 do + if CurrentHedgehog ~= nil then + if CurrentHedgehog == hhs[i] then + fThief[wtf] = hhs[i] + end + end + end + AddCaption(loc("Flag captured!")) + + --below line doesnt usually get called + --else + -- now gets called if you go over your own flag, presumably + --AddCaption("Hmm... that wasn't supposed to happen...") + end + +end + +function CheckFlagProximity() + + for i = 0, 1 do + if fGear[i] ~= nil then + + g1X = fGearX[i] + g1Y = fGearY[i] + + g2X, g2Y = GetGearPosition(CurrentHedgehog) + + q = g1X - g2X + w = g1Y - g2Y + dist = (q*q) + (w*w) + + if dist < 500 then --1600 + DoFlagStuff(fGear[i]) + end + end + end + +end + + +function HandleRespawns() + + for i = 0, 1 do + + if fNeedsRespawn[i] == true then + fGear[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true) + fGearX[i] = fSpawnX[i] + fGearY[i] = fSpawnY[i] + --fGear[i] = SpawnAmmoCrate(fSpawnX[i],fSpawnY[i],amSkip) + fNeedsRespawn[i] = false + fIsMissing[i] = false -- new, this should solve problems of a respawned flag being "returned" when a player tries to score + AddCaption(loc("Flag respawned!")) + end + + end + +end + + +function FlagThiefDead(gear) + + if (gear == fThief[0]) then + wtf = 0 + bbq = 1 + elseif (gear == fThief[1]) then + wtf = 1 + bbq = 0 + end + + if fThief[wtf] ~= nil then + -- falls into water + --ShowMission(LAND_HEIGHT, fThiefY[wtf], (LAND_HEIGHT - fThiefY[wtf]), 0, 0) + if (LAND_HEIGHT - fThiefY[wtf]) < 15 then + fIsMissing[wtf] = true + fNeedsRespawn[wtf] = true + HandleRespawns() + --AddCaption("hah??") + else --normally + fGearX[wtf] = fThiefX[wtf] + fGearY[wtf] = fThiefY[wtf] + fGear[wtf] = AddVisualGear(fGearX[wtf],fGearY[wtf],vgtCircle,0,true) + --fGear[wtf] = AddVisualGear(fThiefX[wtf],fThiefY[wtf],vgtCircle,0,true) + end + + AddVisualGear(fThiefX[wtf], fThiefY[wtf], vgtBigExplosion, 0, false) + fThief[wtf] = nil + end + +end + +function HandleCircles() + + fGearTimer = fGearTimer + 1 + if fGearTimer == 50 then + fGearTimer = 0 + fGearRad = fGearRad + 1 + if fGearRad > fGearRadMax then + fGearRad = fGearRadMin + end + end + + for i = 0, 1 do + + --SetVisualGearValues(fSpawnC[i], fSpawnX[i],fSpawnY[i], 20, 200, 0, 0, 100, 50, 3, fCol[i]) -- draw a circ for spawning area + + if fIsMissing[i] == false then -- draw a flag marker at the flag's spawning place + SetVisualGearValues(fCirc[i], fSpawnX[i],fSpawnY[i], 20, 20, 0, 10, 0, 33, 3, fCol[i]) + if fGear[i] ~= nil then -- draw the flag gear itself + SetVisualGearValues(fGear[i], fSpawnX[i],fSpawnY[i], 20, 200, 0, 0, 100, fGearRad, 2, fCol[i]) + end + elseif (fIsMissing[i] == true) and (fNeedsRespawn[i] == false) then + if fThief[i] ~= nil then -- draw circle round flag carrier + SetVisualGearValues(fCirc[i], fThiefX[i], fThiefY[i], 20, 200, 0, 0, 100, 33, 3, fCol[i]) + --AddCaption("circle marking carrier") + elseif fThief[i] == nil then -- draw cirle round dropped flag + --g1X,g1Y,g4,g5,g6,g7,g8,g9,g10,g11 = GetVisualGearValues(fGear[i]) + --SetVisualGearValues(fCirc[i], g1X, g1Y, 20, 200, 0, 0, 100, 33, 2, fCol[i]) + SetVisualGearValues(fCirc[i], fGearX[i], fGearY[i], 20, 200, 0, 0, 100, 33, 3, fCol[i]) + --AddCaption('dropped circle marker') + if fGear[i] ~= nil then -- flag gear itself + --SetVisualGearValues(fGear[i], g1X, g1Y, 20, 200, 0, 0, 100, 10, 4, fCol[i]) + SetVisualGearValues(fGear[i], fGearX[i], fGearY[i], 20, 200, 0, 0, 100, fGearRad, 2, fCol[i]) + --AddCaption('dropped flag itself') + end + end + end + + if fNeedsRespawn[i] == true then -- if the flag has been destroyed, no need for a circle + SetVisualGearValues(fCirc[i], fSpawnX[i],fSpawnY[i], 20, 200, 0, 0, 100, 0, 0, fCol[i]) + --AddCaption("needs respawn = true. flag 'destroyed'?") + end + end + +end + +------------------------ +-- general methods +------------------------ + +function CheckDistance(gear1, gear2) + + g1X, g1Y = GetGearPosition(gear1) + g2X, g2Y = GetGearPosition(gear2) + + g1X = g1X - g2X + g1Y = g1Y - g2Y + z = (g1X*g1X) + (g1Y*g1Y) + + dist = z + + return dist + +end + +function RebuildTeamInfo() + + + -- make a list of individual team names + for i = 0, 5 do + teamNameArr[i] = i + teamSize[i] = 0 + teamIndex[i] = 0 + 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 + 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 + +function StartTheGame() + + gameStarted = true + AddCaption(loc("Game Started!")) + + for i = 0, 1 do + + -- if someone uses kamikaze downwards, this can happen as the hog won't respawn + if (LAND_HEIGHT - fSpawnY[i]) < 0 then + tempG = AddGear(0, 0, gtTarget, 0, 0, 0, 0) + FindPlace(tempG, true, 0, LAND_WIDTH, true) + fSpawnX[i], fSpawnY[i] = GetGearPosition(tempG) + DeleteGear(tempG) + end + + fGear[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true) + fCirc[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true) + fSpawnC[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true) + + fGearX[i] = fSpawnX[i] + fGearY[i] = fSpawnY[i] + + fCol[i] = GetClanColor(i) + fIsMissing[i] = false + fNeedsRespawn[i] = false + fCaptures[i] = 0 + + --SetVisualGearValues(zxc, 1000,1000, 20, 100, 0, 10, 1, 100, 5, GetClanColor(0)) + + SetVisualGearValues(fSpawnC[i], fSpawnX[i],fSpawnY[i], 20, 100, 0, 10, 0, 75, 5, fCol[i]) + --SetVisualGearValues(fCirc[i], fSpawnX[i],fSpawnY[i], 20, 20, 0, 10, 0, 33, 3, fCol[i]) + + + end + +end + +------------------------ +-- game methods +------------------------ + +function onGameInit() + + -- Things we don't modify here will use their default values. + + GameFlags = band(bor(GameFlags, gfDivideTeams), bnot(gfKing + gfForts)) + SuddenDeathTurns = 99 -- suddendeath is off, effectively + --TurnTime = 30000 -- (was 30) The time the player has to move each round (in ms) + --Delay = 10 -- The delay between each round + +end + + +function onGameStart() + + --ShowMission(loc(caption), loc(subcaption), loc(goal), 0, 0) + ShowMission(loc("CAPTURE THE FLAG"), loc("by mikade"), loc("CUSTOM BUILD 0.2"), 0, 0) + + RebuildTeamInfo() + + -- should gfDivideTeams do this automatically? + --[[for i = 0, (TeamsCount-1) do + for g = teamIndex[i], (teamIndex[i]+teamSize[i]-1) do + if GetHogClan(hhs[g]) == 0 then + FindPlace(hhs[g], false, 0, LAND_WIDTH/2) + elseif GetHogClan(hhs[g]) == 1 then + FindPlace(hhs[g], false, LAND_WIDTH/2, LAND_WIDTH) + end + end + end]] + + fPlaced[0] = false + fPlaced[1] = false + + --zxc = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true) + + + --SetVisualGearValues(zxc, 1000,1000, 20, 255, 1, 10, 0, 200, 1, GetClanColor(0)) + --minO,max0 -glowyornot --pulsate timer -- fuckall -- radius -- width -- colour +end + + +function onNewTurn() + + gameTurns = gameTurns + 1 + + if lastTeam ~= GetHogTeamName(CurrentHedgehog) then + lastTeam = GetHogTeamName(CurrentHedgehog) + end + + --AddCaption("Handling respawns") + if gameStarted == true then + HandleRespawns() + --new method of placing starting flags + elseif gameTurns == 1 then + ShowMission(loc("CAPTURE THE FLAG"), loc("Flags will be placed where each team ends their turn."), "", 0, 0) + elseif gameTurns == 2 then + fPlaced[0] = true + ShowMission(loc("CAPTURE THE FLAG"), loc("RULES OF THE GAME [Press ESC to view]"), loc(" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"), 0, 0) + elseif gameTurns == 3 then + fPlaced[1] = true + StartTheGame() + end + +end + +function onGameTick() + + -- onRessurect calls AFTER you have resurrected, + -- so keeping track of x,y a few milliseconds before + -- is useful + --FTTC = FTTC + 1 + --if FTTC == 100 then + -- FTTC = 0 + for i = 0,1 do + if fThief[i] ~= nil then + fThiefX[i] = GetX(fThief[i]) + fThiefY[i] = GetY(fThief[i]) + end + end + --end + + -- things we wanna check often + if (CurrentHedgehog ~= nil) then + --AddCaption(LAND_HEIGHT - GetY(CurrentHedgehog)) + --AddCaption(GetX(CurrentHedgehog) .. "; " .. GetY(CurrentHedgehog)) + --CheckTeleporters() + + end + + if gameStarted == true then + HandleCircles() + if CurrentHedgehog ~= nil then + CheckFlagProximity() + end + elseif CurrentHedgehog ~= nil then -- if the game hasn't started yet, keep track of where we are gonna put the flags on turn end + + if GetHogClan(CurrentHedgehog) == 0 then + i = 0 + elseif GetHogClan(CurrentHedgehog) == 1 then + i = 1 + end + + fSpawnX[i] = GetX(CurrentHedgehog) + fSpawnY[i] = GetY(CurrentHedgehog) + + end + +end + +function onGearResurrect(gear) + + --AddCaption("A gear has been resurrected!") + + -- mark the flag thief as dead if he needed a respawn + for i = 0,1 do + if gear == fThief[i] then + FlagThiefDead(gear) + end + end + + -- should be covered by gfDivideTeams, actually + -- place hogs belonging to each clan either left or right side of map + --if GetHogClan(gear) == 0 then + -- FindPlace(gear, false, 0, LAND_WIDTH/2) + --elseif GetHogClan(gear) == 1 then + -- FindPlace(gear, false, LAND_WIDTH/2, LAND_WIDTH) + --end + + AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) + +end + +function onGearDamage(gear, damage) +-- +end + +function onGearAdd(gear) + + if GetGearType(gear) == gtHedgehog then + hhs[numhhs] = gear + numhhs = numhhs + 1 + SetEffect(gear, heResurrectable, true) + end + +end + +function onGearDelete(gear) + + if GetGearType(gear) == gtHedgehog then + --AddCaption("gear deleted!") + for i = 0, (numhhs-1) do + if gear == hhs[i] then + + for i = 0,1 do + if gear == fThief[i] then + FlagThiefDead(gear) + end + end + hhs[i] = nil + --AddCaption("for real") + end + end + end + +end