--[[ ___ ___ ( ) ( )___ .-. .-. ___ ___ | |_ .---. ___ .-. | |_( ) ' ( )( ( __) / .-, ( ) ( __)| .-. .-. | | | | | | (__) ; || .-. .| || | | | | | | | | | | ___ .'` || | | || | ___| | | | | | | | | | |( / .'| || | | || |( )| | | | | | | | | | | | | / | || | | || | | || | | | | | | ; ' | ' | ; | ; || | | || ' | || | | | | ' `-' / ' `-' ' `-' || | | |' `-' ;(___)(___)(___'.__.' `.__.`.__.'_(___)(___)`.__.---- Recommended settings:---- * one hedgehog per team (forced by game)---- * one team per clan---- * 'Small' one-island map--]]HedgewarsScriptLoad("/Scripts/Locale.lua")HedgewarsScriptLoad("/Scripts/Tracker.lua")HedgewarsScriptLoad("/Scripts/Params.lua")--[[ MUTANT SCRIPT]]local hhs = {}local crates = {}local numhhs = 0local meh = falselocal gameOver=falselocal mutant = nillocal mutant_base_health = 200local mutant_base_disease = 25local disease_timer = 2000local kill_reward = nillocal mt_hurt=falselocal killsCounter = 0local team_fire_punishment = 3local mutant_kill_reward = 2local hh_weapons = { amBazooka, amGrenade, amShotgun, amMine}local mt_weapons = {amWatermelon, amHellishBomb, amBallgun, amRCPlane, amTeleport}local disease=0local timer=0local winScore = 15local hogsLimit = 1local teamsDead = {}local circles = {}local circleFrame = -1-- Variables for custom achievements-- Most kills in 1 turnlocal recordKills = 0local recordKillsHogName = nillocal recordKillsTeamName = nil-- Most suicideslocal recordSuicides = 0local recordSuicidesHogName = nillocal recordSuicidesTeamName = nil-- Most skipslocal recordSkips = 0local recordSkipsHogName = nillocal recordSkipsTeamName = nil-- Most crates collectedlocal recordCrates = 0local recordCratesHogName = nillocal recordCratesTeamName = nil-- Most deathslocal recordDeaths = 0local recordDeathsHogName = nillocal recordDeathsTeamName = nil-- Total killed hedgehogslocal totalKills = 0-- Total damagelocal totalDamage = 0local mutantHat = "WhySoSerious"local feederHat = "poke_slowpoke"function rules() local mineStr if MinesTime < 0 then mineStr = loc("Mines time: 0s-5s") else mineStr = string.format(loc("Mines explode after %d s."), div(MinesTime, 1000)) end local ruleSet = loc("Hedgehogs will be revived after their death.") .. "|" .. mineStr .. "|" .. loc("The first hedgehog to kill someone becomes the Mutant.") .. "|" .. loc("The Mutant has super weapons and a lot of health.") .. "|" .. loc("The Mutant loses health quickly, but gains health by killing.") .. "|" .. " |" .. loc("Score points by killing other hedgehogs.") .. "|" .. loc("The hedgehog with least points (or most deaths) becomes the Bottom Feeder.") .. "|" .. loc("The score and deaths are shown next to the team bar.") .. "|" .. string.format(loc("Goal: Score %d points or more to win!"), winScore) .. "|" .. " |" .. loc("Scoring: ") .. "|" .. loc("+2 for becoming the Mutant") .. "|" .. loc("+1 to the Mutant for killing anyone") .. "|" .. loc("+1 to the Bottom Feeder for killing anyone") .. "|" .. loc("-1 to anyone for a suicide") return ruleSetendfunction showStartingInfo() ShowMission(loc("Mutant"), loc("A Hedgewars tag game"), rules(), -amWatermelon, 5000)endfunction onGameInit() -- Sudden Death would be weird WaterRise = 0 HealthDecrease = 0 -- Weapons must be reset for the Mutant mechanic to work EnableGameFlags(gfResetWeps) -- King Mode messes with game too much DisableGameFlags(gfKing)endfunction limitHogs(gear) cnthhs = cnthhs + 1 if cnthhs > 1 then hogLimitHit = true SetEffect(gear, heResurrectable, 0) setGearValue(gear, "excess", true) DeleteGear(gear) endendfunction onGameStart() if ClansCount >= 2 then SendHealthStatsOff() SendAchievementsStatsOff() end SendRankingStatsOff() trackTeams() teamScan() runOnHogs(saveStuff) hogLimitHit = false for i=0 , TeamsCount - 1 do cnthhs = 0 runOnHogsInTeam(limitHogs, GetTeamName(i)) end if hogLimitHit then WriteLnToChat(loc("Only one hog per team allowed! Excess hogs will be removed.")) end showStartingInfo()endfunction giveWeapons(gear) if gear == mutant then AddAmmo(gear, amRope) for i=1, #mt_weapons do AddAmmo(gear, mt_weapons[i]) end else for i=1, #hh_weapons do AddAmmo(gear,hh_weapons[i]) end endendfunction onAmmoStoreInit() SetAmmo(amSkip, 9, 0, 0, 0) SetAmmo(amRope,0,1,0,5) SetAmmo(amSnowball,0,1,0,1) for i=1, #hh_weapons do SetAmmo(hh_weapons[i], 0, 0, 0, 1) end for i=1, #mt_weapons do SetAmmo(mt_weapons[i], 0, 3, 0, 1) endendfunction drawCircles() for i = 0, #hhs do if circles[hhs[i]] ~= nil then DeleteVisualGear(circles[hhs[i]]) circles[hhs[i]] = nil end if hhs[i] ~= CurrentHedgehog then if mutant == nil then circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080) elseif CurrentHedgehog == mutant then circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070) elseif getGearValue(CurrentHedgehog, "Feeder") and hhs[i] ~= mutant then circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070) elseif hhs[i] == mutant then circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080) end end end circleFrame = 0endfunction onNewTurn() trackTeams() killsCounter = 0 if mutant == nil and TotalRounds >= 0 then AddCaption( loc("First killer will mutate"), capcolDefault, capgrpGameState ) end checkScore() for i=0, TeamsCount-1 do SendStat(siClanHealth, getTeamValue(GetTeamName(i), "Score"), GetTeamName(i)) end giveWeapons(CurrentHedgehog) drawCircles() setAIHints() kill_reward= numhhs*10 if CurrentHedgehog == mutant then mt_hurt=true disease= mutant_base_disease - numhhs else mt_hurt=false end setGearValue(CurrentHedgehog, "Alive", true)endfunction countBodies() if killsCounter == 2 then AddCaption(loc("Double kill!"), capcolDefault, capgrpGameState ) elseif killsCounter == 3 then AddCaption(loc("Mega kill!"), capcolDefault, capgrpGameState ) PlaySound(sndRegret) elseif killsCounter == 4 then AddCaption(loc("Ultra kill!"), capcolDefault, capgrpGameState ) elseif killsCounter == 5 then AddCaption(loc("Monster kill!"), capcolDefault, capgrpGameState ) PlaySound(sndIllGetYou) elseif killsCounter == 6 then AddCaption(loc("Ludicrous kill!"), capcolDefault, capgrpGameState ) PlaySound(sndNutter) elseif killsCounter == 7 then AddCaption(loc("Holy shit!"), capcolDefault, capgrpGameState ) PlaySound(sndLaugh) elseif killsCounter > 8 then AddCaption(loc("Insanity!"), capcolDefault, capgrpGameState ) end if killsCounter > recordKills then recordKills = killsCounter recordKillsHogName = getGearValue(CurrentHedgehog, "Name") recordKillsTeamName = GetHogTeamName(CurrentHedgehog) endendfunction onGameTick() if circleFrame > -1 then for i = 0, #hhs do if circles[hhs[i]] ~= nil and hhs[i]~= nil then hhx, hhy = GetGearPosition(hhs[i]) SetVisualGearValues(circles[hhs[i]], hhx + 1, hhy - 3, 0, 0, 0, 0, 0, 40 - (circleFrame % 25)) end end circleFrame = circleFrame + 0.06 if circleFrame >= 25 then for i = 0, #hhs do if circles[hhs[i]] ~= nil then DeleteVisualGear(circles[hhs[i]]) circles[hhs[i]] = nil end end end end if (TurnTimeLeft==0 or band(GetState(mutant), gstHHDriven) == 0) and mt_hurt then mt_hurt = false end -- Mutant's disease -- Hurt Mutant during its turn time -- Mutant's health is safe in ready phase if mt_hurt and mutant~=nil and ReadyTimeLeft == 0 then timer = timer + 1 if timer > disease_timer then timer = 0 local h = GetHealth(mutant)-disease SetHealth(mutant, h) -- Low health warning if h <= 75 then PlaySound(sndPoisonMoan, mutant) elseif h <= 150 then PlaySound(sndPoisonCough, mutant) end local tag = AddVisualGear(GetX(mutant), GetY(mutant)-5, vgtHealthTag, disease, true) SetVisualGearValues(tag, nil, nil, nil, nil, nil, nil, nil, nil, nil, GetClanColor(GetHogClan(mutant))) if GetHealth(mutant)<=0 then SetHealth(mutant,0) mt_hurt= false setGearValue(mutant,"SelfDestruct",true) EndTurn() end end endend--[[Forces the special mutant/feeder names and hats only to betaken by those who deserved it.Names and hats will be changed (and ridiculed) if neccesary.]]function exposeIdentityTheft(gear) local lon = string.lower(GetHogName(gear)) -- lowercase origina name local name, hat -- Change name if hog uses a reserved one if lon == "mutant" or lon == string.lower(loc("Mutant")) then SetHogName(gear, loc("Identity Thief")) SetHogHat(gear, "Disguise") elseif lon == "bottom feeder" or lon == string.lower(loc("Bottom Feeder")) then -- Word play on "Bottom Feeder". Someone who is low on cotton. :D -- Either translate literally or make up your ow word play SetHogName(gear, loc("Cotton Needer")) SetHogHat(gear, "StrawHat") end -- Strip hog off its special hat if GetHogHat(gear) == mutantHat or GetHogHat(gear) == feederHat then SetHogHat(gear, "NoHat") endendfunction saveStuff(gear) exposeIdentityTheft(gear) setGearValue(gear,"Name",GetHogName(gear)) setGearValue(gear,"Hat",GetHogHat(gear))endfunction armageddon(gear) SetState(gear, gstLoser) SetEffect(gear, heResurrectable, 0) SetHealth(gear, 0)endfunction renderScores() for i=0, TeamsCount-1 do local name = GetTeamName(i) SetTeamLabel(name, string.format(loc("%d | %d"), getTeamValue(name, "Score"), getTeamValue(name, "DeadHogs"))) endendfunction createEndGameStats() SendStat(siGraphTitle, loc("Score graph")) local teamsSorted = {} for i=0, TeamsCount-1, 1 do teamsSorted[i+1] = GetTeamName(i) end -- Achievements stuff local achievements = 0 --- Most kills per turn if recordKills >= 3 then SendStat(siMaxStepKills, string.format("%d %s (%s)", recordKills, recordKillsHogName, recordKillsTeamName)) achievements = achievements + 1 end --- Most crates collected if recordCrates >= 5 then SendStat(siCustomAchievement, string.format(loc("%s (%s) was the greediest hedgehog and collected %d crates."), recordCratesHogName, recordCratesTeamName, recordCrates)) achievements = achievements + 1 end --- Most suicides if recordSuicides >= 5 then SendStat(siCustomAchievement, string.format(loc("%s (%s) hate life and suicided %d times."), recordSuicidesHogName, recordSuicidesTeamName, recordSuicides)) achievements = achievements + 1 end --- Most deaths if recordDeaths >= 5 then SendStat(siCustomAchievement, string.format(loc("Poor %s (%s) died %d times."), recordDeathsHogName, recordDeathsTeamName, recordDeaths)) achievements = achievements + 1 end --- Most skips if recordSkips >= 3 then SendStat(siMaxTurnSkips, string.format("%d %s (%s)", recordSkips, recordSkipsHogName, recordSkipsTeamName)) achievements = achievements + 1 end --- Total damage if totalDamage >= 900 then SendStat(siCustomAchievement, string.format(loc("%d damage was dealt in this game."), totalDamage)) achievements = achievements + 1 end --- Total kills if totalKills >= 20 or (achievements <= 0 and totalKills >= 1) then SendStat(siKilledHHs, tostring(totalKills)) achievements = achievements + 1 end -- Score and stats stuff local showScore = "" local rank = 0 local rankPlus = 1 local prevScore table.sort(teamsSorted, function(team1, team2) return getTeamValue(team1, "Score") > getTeamValue(team2, "Score") end) for i=1, TeamsCount do local score = getTeamValue(teamsSorted[i], "Score") local deaths = getTeamValue(teamsSorted[i], "DeadHogs") if i == 1 or score < prevScore then rank = rank + rankPlus rankPlus = 1 prevScore = score else rankPlus = rankPlus + 1 end SendStat(siPointType, "!POINTS") SendStat(siTeamRank, rank) SendStat(siPlayerKills, score, teamsSorted[i]) showScore = showScore .. string.format(loc("%s: %d (deaths: %d)"), teamsSorted[i], score, deaths) .. "|" end if getTeamValue(teamsSorted[1], "Score") == getTeamValue(teamsSorted[2], "Score") then -- The first two teams have the same score! Round is drawn. return nil else ShowMission(loc("Mutant"), loc("Final result"), string.format(loc("Winner: %s"), teamsSorted[1]) .. "| |" .. loc("Scores:") .. " |" .. showScore, 4, 15000) -- return winning team return teamsSorted[1] endendfunction checkScore()local lowest_score_team = nillocal min_score=nillocal winTeam = nillocal only_low_score = true for i=0, TeamsCount-1 do local teamName = GetTeamName(i) if not teamsDead[teamName] then local curr_score = getTeamValue(teamName, "Score") runOnHogsInTeam(removeFeeder, teamName) if curr_score >= winScore then gameOver = true winTeam = teamName end if min_score==nil then min_score= curr_score lowest_score_team = teamName else if curr_score <= min_score then if curr_score == min_score then if getTeamValue(teamName, "DeadHogs") == getTeamValue(lowest_score_team, "DeadHogs") then only_low_score = false else if getTeamValue(teamName, "DeadHogs") > getTeamValue(lowest_score_team, "DeadHogs") then lowest_score_team = teamName end only_low_score = true end else min_score= curr_score lowest_score_team = teamName only_low_score = true end end end end end if gameOver then EndTurn(true) for i=0, TeamsCount-1 do local teamName = GetTeamName(i) if teamName~=winTeam then runOnHogsInTeam(armageddon, teamName) end end createEndGameStats() else if only_low_score then runOnHogsInTeam(setFeeder, lowest_score_team) end if meh == false then meh = true end endendfunction backToNormal(gear) SetHogName(gear, getGearValue(gear,"Name")) SetHogHat(gear, 'NoHat') SetHogHat(gear, getGearValue(gear,"Hat")) setGearValue(mutant,"SelfDestruct",false) mt_hurt=false mutant=nilendfunction setAIHints() for i = 0, #hhs do if mutant == nil or hhs[i] == mutant or CurrentHedgehog == mutant or getGearValue(CurrentHedgehog, "Feeder") then SetGearAIHints(hhs[i], aihUsualProcessing) else SetGearAIHints(hhs[i], aihDoesntMatter) end end for k,v in pairs(crates) do if CurrentHedgehog == mutant and v ~= nil then SetGearAIHints(v, aihDoesntMatter) else SetGearAIHints(v, aihUsualProcessing) end endendfunction removeFeeder(gear) if gear~=nil then setGearValue(gear,"Feeder",false) if gear~= mutant then SetHogName(gear, getGearValue(gear,"Name") ) SetHogHat(gear, 'NoHat') SetHogHat(gear, getGearValue(gear,"Hat")) end endendfunction setFeeder(gear) if gear~= mutant and gear~= nil then SetHogName(gear, loc("Bottom Feeder")) SetHogHat(gear, feederHat) setGearValue(gear,"Feeder", true) endendfunction setMutantStuff(gear) mutant = gear SetHogName(gear, loc("Mutant")) SetHogHat(gear, mutantHat) SetHealth(gear, ( mutant_base_health + numhhs*25) ) SetEffect(gear, hePoisoned, 1) setGearValue(mutant,"SelfDestruct",false) setGearValue(gear, "Feeder", false) AddCaption(string.format(loc("%s has mutated! +2 points"), getGearValue(gear, "Name")), GetClanColor(GetHogClan(gear)), capgrpMessage) if TurnTimeLeft > 0 then EndTurn(true) end AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) PlaySound(sndSuddenDeath)endfunction teamScan() for j=0, TeamsCount-1 do teamName = GetTeamName(j) teamsDead[teamName] = false setTeamValue(teamName, "Score",0) setTeamValue(teamName, "Suicides",0) setTeamValue(teamName, "Skips",0) setTeamValue(teamName, "Crates",0) setTeamValue(teamName, "DeadHogs",0) end renderScores() ---***---endfunction set_Mutant_and_Score(gear)local curr_team = GetHogTeamName(CurrentHedgehog) if gear == CurrentHedgehog then if CurrentHedgehog == mutant then PlaySound(sndHomerun) if getGearValue(gear, "SelfDestruct")==false then decreaseTeamValue(curr_team,"Score") end backToNormal(gear) else decreaseTeamValue(curr_team,"Score") end else if gear == mutant then backToNormal(mutant) if curr_team ~=GetHogTeamName(gear) then if getGearValue(CurrentHedgehog, "Alive") then setMutantStuff(CurrentHedgehog) setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward)) end else setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) increaseTeamValue(curr_team,"Suicides") if(getTeamValue(curr_team, "Suicides") > recordSuicides) then recordSuicides = getTeamValue(curr_team, "Suicides") recordSuicidesHogName = getGearValue(CurrentHedgehog, "Name") recordSuicidesTeamName = curr_team end AddCaption(loc("-1 point"), GetClanColor(GetHogClan(CurrentHedgehog)), capgrpMessage) end else if mutant==nil then if curr_team ~=GetHogTeamName(gear) then if getGearValue(CurrentHedgehog, "Alive") then setMutantStuff(CurrentHedgehog) setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward)) else increaseTeamValue(curr_team,"Score") end else setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) increaseTeamValue(curr_team,"Suicides") if(getTeamValue(curr_team, "Suicides") > recordSuicides) then recordSuicides = getTeamValue(curr_team, "Suicides") recordSuicidesHogName = getGearValue(CurrentHedgehog, "Name") recordSuicidesTeamName = curr_team end AddCaption(loc("-1 point"), GetClanColor(GetHogClan(CurrentHedgehog)), capgrpMessage) end else if curr_team ~=GetHogTeamName(gear) then if CurrentHedgehog==mutant and getGearValue(mutant,"SelfDestruct")==false then HealHog(CurrentHedgehog, kill_reward) AddCaption(loc("+1 point"), GetClanColor(GetHogClan(CurrentHedgehog)), capgrpMessage) increaseTeamValue(curr_team,"Score") end if getGearValue(CurrentHedgehog,"Feeder") then increaseTeamValue(curr_team,"Score") AddCaption(loc("+1 point"), GetClanColor(GetHogClan(CurrentHedgehog)), capgrpMessage) end else setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) AddCaption(loc("+1 point"), GetClanColor(GetHogClan(CurrentHedgehog)), capgrpMessage) end end end endendfunction onGearResurrect(gear)if not gameOver then if GetGearType(gear) == gtHedgehog then increaseTeamValue(GetHogTeamName(gear), "DeadHogs") totalKills = totalKills + 1 if(getTeamValue(GetHogTeamName(gear), "DeadHogs") > recordDeaths) then recordDeaths = getTeamValue(GetHogTeamName(gear), "DeadHogs") recordDeathsHogName = getGearValue(gear, "Name") recordDeathsTeamName = GetHogTeamName(gear) end if gear==CurrentHedgehog then setGearValue(CurrentHedgehog, "Alive", false) end set_Mutant_and_Score(gear) if gear~=CurrentHedgehog then killsCounter = killsCounter + 1 countBodies() end AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) PlaySound(sndWhack) renderScores() endendendfunction onGearDamage(gear, damage) if not gameOver and GetGearType(gear) == gtHedgehog then totalDamage = totalDamage + damage endendfunction onSkipTurn() -- Record skips for achievement local team = GetHogTeamName(CurrentHedgehog) increaseTeamValue(team, "Skips") if(getTeamValue(team, "Skips") > recordSkips) then recordSkips = getTeamValue(team, "Skips") recordSkipsHogName = getGearValue(CurrentHedgehog, "Name") recordSkipsTeamName = team endendfunction onGearAdd(gear) -- Catch hedgehogs for the tracker if GetGearType(gear) == gtHedgehog then trackGear(gear) hhs[numhhs] = gear numhhs = numhhs + 1 SetEffect(gear, heResurrectable, 1) elseif GetGearType(gear) == gtCase then crates[gear] = gear elseif GetGearType(gear) == gtATFinishGame then if not gameOver then local winner = createEndGameStats() if winner then SendStat(siGameResult, string.format(loc("%s wins!"), winner)) AddCaption(string.format(loc("%s wins!"), winner), capcolDefault, capgrpGameState) end gameOver = true end endendfunction checkEmptyTeam (teamName) for i=0 , #hhs do if hhs[i]~=nil then if teamName == GetHogTeamName(hhs[i]) then return false end end end return trueendfunction onGearDelete(gear) -- Remove hogs that are gone if GetGearType(gear) == gtHedgehog then numhhs = numhhs - 1 local found for i=0, #hhs do if hhs[i] == gear then found = i break end end for i = found, #hhs - 1 do hhs[i] = hhs[i + 1] end hhs[#hhs] = nil local t_name = GetHogTeamName(gear) if checkEmptyTeam(t_name) then for i = 0, TeamsCount - 1 do if GetTeamName(i) == t_name then found = i teamsDead[t_name] = true break end end end if getGearValue(gear, "excess") ~= true and band(GetState(gear), gstDrowning) == 0 then AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) end trackDeletion(gear) elseif GetGearType(gear) == gtCase then crates[gear] = nil -- Check if a crate has been collected if band(GetGearMessage(gear), gmDestroy) ~= 0 and CurrentHedgehog ~= nil then -- Update crate collection achievement increaseTeamValue(GetHogTeamName(CurrentHedgehog), "Crates") if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Crates") > recordCrates) then recordCrates = getTeamValue(GetHogTeamName(CurrentHedgehog), "Crates") recordCratesHogName = getGearValue(CurrentHedgehog, "Name") recordCratesTeamName = GetHogTeamName(CurrentHedgehog) end end endendfunction onParameters() parseParams() winScore = tonumber(params["winscore"]) or winScoreend--[[S T A R R I N G prof - Coding, implementing and evangelism vos - Initial idea and script improvements mikade - Moving the `how to play` into the game so that people know `how to play`, and whitespace :D--]]