--4v4 Hot Potato Minigame

import(Module_System)
import(Module_Players)
import(Module_Defines)
import(Module_PopScript)
import(Module_Game)
import(Module_Objects)
import(Module_Map)
import(Module_Math)
import(Module_MapWho)
import(Module_String)
import(Module_ImGui)
import(Module_Draw)
import(Module_System)
import(Module_Globals)
import(Module_Person)
import(Module_Table)
import(Module_DataTypes)
import(Module_Sound)
import(Module_Commands)
import(Module_Level)
import(Module_Building)
import(Module_Spells)
include("zz4_assets.lua")
for i = 0,7 do set_player_cannot_build(M_BUILDING_GUARD_POST, i) end
--teams old vs new tribes
for i = 0,3 do
	for j = 0,3 do
		if j ~= i then
			set_players_allied(i,j)
			set_players_allied(j,i)
		end
	end
end
for i = 4,7 do
	for j = 4,7 do
		if j ~= i then
			set_players_allied(i,j)
			set_players_allied(j,i)
		end
	end
end
local gs = gsi()
local gns = gnsi()
_gnsi = gnsi()
_gsi = gsi()

for i=0,7 do
  set_player_reinc_site_off(getPlayer(i))
  SET_NO_REINC(i)
  if getShaman(i) ~= nil then
		getShaman(i).Flags = EnableFlag(getShaman(i).Flags, TF_STATE_LOCKED)
	end
end
_gnsi.GameParams.Flags2 = _gnsi.GameParams.Flags2 | GPF2_GAME_NO_WIN
_gnsi.GameParams.Flags3 = _gnsi.GameParams.Flags3 | GPF3_NO_GAME_OVER_PROCESS

local win = -1
local timer = -1
local exptimer = 12*10 + 12
local captains = {0,7}
local Noncaptains = {1,2,3,4,5,6}
local f = nil
local stagepause = -1
local dynamitedelay = 0
local bombTimer = -1

local team1Score = 0
local team2Score = 0
local giveSpells = {M_SPELL_INSECT_PLAGUE}
----------------------------------------------------spell constants
tmi = thing_move_info()
tmi[TMI_PERSON_MEDICINE_MAN].BaseSpeed = 58
sti = spells_type_info()

local throwStone = M_SPELL_INSECT_PLAGUE
sti[throwStone].OneOffMaximum = 2
sti[throwStone].Cost = 10000
sti[throwStone].WorldCoordRange = 4096
sti[throwStone].CursorSpriteNum = 166
sti[throwStone].AvailableSpriteIdx = 2117
sti[throwStone].NotAvailableSpriteIdx = 2117
sti[throwStone].ClickedSpriteIdx = 2117

local addedTimer = 8
local timerUp = M_SPELL_HYPNOTISM
sti[timerUp].OneOffMaximum = 1
sti[timerUp].WorldCoordRange = 4096
sti[timerUp].CursorSpriteNum = 27
sti[timerUp].AvailableSpriteIdx = 2099
sti[timerUp].NotAvailableSpriteIdx = 2099
sti[timerUp].ClickedSpriteIdx = 2099
local timerDown = M_SPELL_CONVERT_WILD
sti[timerDown].OneOffMaximum = 1
sti[timerDown].WorldCoordRange = 4096
sti[timerDown].CursorSpriteNum = 27
sti[timerDown].AvailableSpriteIdx = 2100
sti[timerDown].NotAvailableSpriteIdx = 2100
sti[timerDown].ClickedSpriteIdx = 2100
set_player_can_cast(timerDown,0)
set_player_can_cast(timerUp,0)
GIVE_ONE_SHOT(timerDown,0)
GIVE_ONE_SHOT(timerUp,0)
for i = 0,7 do
	if getShaman(i) ~= nil then
		getShaman(i).Flags = EnableFlag(getShaman(i).Flags, TF_STATE_LOCKED)
	end
end

set_correct_gui_menu()

_constants = constants();
_constants.ShamenDeadManaPer256Gained = 4
_constants.ShamenDeadManaPer256Lost = 4
--------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------
pl = {
			[0] =
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 2,
				name = "blue",
				id = 0,
				cor = marker_to_coord3d(0),
				drawClr = 4,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			},
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 2,
				name = "red",
				id = 1,
				cor = marker_to_coord3d(1),
				drawClr = 12,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			},
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 2,
				name = "yellow",
				id = 2,
				cor = marker_to_coord3d(2),
				drawClr = 5,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			},
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 2,
				name = "green",
				id = 3,
				cor = marker_to_coord3d(3),
				drawClr = 3,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			},
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 9,
				name = "cyan",
				id = 4,
				cor = marker_to_coord3d(4),
				drawClr = 7,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			},
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 9,
				name = "magenta",
				id = 5,
				cor = marker_to_coord3d(5),
				drawClr = 6,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			},
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 9,
				name = "black",
				id = 6,
				cor = marker_to_coord3d(6),
				drawClr = 16,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			},
			{
				score = 0,
				deaths = 0,
				alive = 1,
				dynamite = 0,
				stun = 0,
				color = 9,
				name = "orange",
				id = 7,
				cor = marker_to_coord3d(7),
				drawClr = 14,
				online = -1,
				stoneCDR = -1,
				stonec3d = -1
			}
}
--set player names and online status
for pn = 0,7,1 do
	if ((_gnsi.Flags & GNS_NETWORK) == GNS_NETWORK) then
		pl[pn].name = get_player_name(pn, true)
		local name = #pl[pn].name
		if name > 8 then
			smallName = ""
			for i = 1,8 do
				smallName = smallName .. string.sub(pl[pn].name, i, i) 
			end
			pl[pn].name = smallName
		end
	end
	if _gsi.Players[pn].PlayerActive == 1 and _gsi.Players[pn].DeadCount == 0 then
		pl[pn].online = 1
	else
		pl[pn].online = 0
		pl[pn].name = "NoPlayer" .. tostring(pn+1) .. ""
		pl[pn].alive = 0
	end
end

function AliveandOnline()
	for i = 0,7,1 do
		if _gsi.Players[i].PlayerActive == 1 and _gsi.Players[0].DeadCount == 0 then
			pl[i].online = 1
		else
			pl[i].online = 0
			pl[i].alive = 0
			pl[i].dynamite = 0
			--if (string.sub(Players[i].name, 1, 1) ~= "*") and (string.sub(Players[i].name, 1, 8) ~= "NoPlayer") then
				--Players[i].name = "*" .. Players[i].name .. "" --disconnected symbol on scoreboard
			--end
			if getShaman(i) ~= nil then
				getShaman(i).u.Pers.Life = 0
			end
		end
		if getShaman(i) == nil then
			pl[i].alive = 0
			pl[i].dynamite = 0
		end
	end
end

function GetRandomPlayerAlive() --find bomber(rng)
	local isAlive = {}
	for i = 0,7 do
		if pl[i].alive == 1 and pl[i].online == 1 then
			table.insert(isAlive,i)
		end
	end
	return isAlive[math.random(1,#isAlive)]
end

function resetStates()
	for i = 0,7,1 do
		if pl[i].online == 1 then
			if getShaman(i) == nil then
				createThing(T_PERSON,M_PERSON_MEDICINE_MAN,i,pl[i].cor,false,false)
			end
			pl[i].stun = 0
			pl[i].dynamite = 0
			pl[i].stoneCDR = -1
			pl[i].alive = 1
			if getShaman(i) ~= nil then
				getShaman(i).Flags3 = DisableFlag(getShaman(i).Flags3, TF3_BLOODLUST_ACTIVE)
				getShaman(i).Flags3 = DisableFlag(getShaman(i).Flags3, TF_NO_MOVE_PROCESS)
			end
			set_player_can_cast(M_SPELL_INSECT_PLAGUE,i)
		end
	end
	dynamitedelay = 0
	local fB = GetRandomPlayerAlive()
	pl[fB].dynamite = 1
	set_player_cannot_cast(M_SPELL_INSECT_PLAGUE,fB)
	queue_sound_event(nil,SND_EVENT_FIGHT_ALARM, SEF_FIXED_VARS)
	tmi[TMI_PERSON_MEDICINE_MAN].BaseSpeed = math.random(40,300)
end

function ThrowStone(pn,c3d)
	local stone = createThing(T_SCENERY,M_SCENERY_ROCK,TRIBE_HOSTBOT,c3d,false,false) ; centre_coord3d_on_block(stone.Pos.D3)
	local dust = createThing(T_EFFECT,M_EFFECT_WW_DUST ,TRIBE_HOSTBOT,c3d,false,false) ; centre_coord3d_on_block(dust.Pos.D3)
	local smoke = createThing(T_EFFECT,M_EFFECT_SMOKE ,TRIBE_HOSTBOT,c3d,false,false) ; centre_coord3d_on_block(smoke.Pos.D3)
	local c2d = Coord2D.new() ; coord3D_to_coord2D(c3d, c2d)
	ProcessGlobalSpecialListAll(0, function(t)
		if t.Type == T_PERSON and t.Owner ~= pn then
			if pl[t.Owner].stun == 0 then
				if get_world_dist_xz(t.Pos.D2,c2d) < 256+128 then
					queue_sound_event(nil,SND_EVENT_FLESH_HIT, SEF_FIXED_VARS)
					pl[t.Owner].stun = 12*3 + 12*(math.random(0,2)) + 4
					getShaman(t.Owner).Flags = EnableFlag(getShaman(t.Owner).Flags, TF_NO_MOVE_PROCESS)
				end
			end
		end
	return true end)
end




function OnTurn()

	if win ~= 1 then AliveandOnline() end
	
	if win == 0 then
		--stagepause
		if stagepause > 0 then
			stagepause = stagepause - 1
		elseif stagepause == 0 then
			stagepause = -1
			resetStates()
			bombTimer = 12*15 + 12*math.random(0,30)
		end
		for i = 0,7,1 do
			if pl[i].online == 1 and getShaman(i) ~= nil then
				--mana
				GIVE_MANA_TO_PLAYER(i,256)
				--process throw stone cdr
				if pl[i].stoneCDR > 0 then
					pl[i].stoneCDR = pl[i].stoneCDR - 1
				elseif pl[i].stoneCDR == 0 then
					pl[i].stoneCDR = -1
					ThrowStone(i,pl[i].stonec3d)
				end
			end
			--process bomber bombTimer sprites (last 5sec)
			if getShaman(i) ~= nil and bombTimer ~= -1 then
				if pl[i].dynamite == 1 then
					if (math.floor(bombTimer/12) >= 0) and (math.floor(bombTimer/12) < 6) then
						local tt = math.floor(bombTimer/12)
						local t = createThing(T_EFFECT,60,8,getShaman(i).Pos.D3,false,false)
						set_thing_draw_info(t,TDI_SPRITE_F1_D1, 2123+tt)
						t.DrawInfo.Alpha = -16
						t.Pos.D3.Ypos = getShaman(i).Pos.D3.Ypos + 128 + 256
						t.u.Effect.Duration = 2
					end
				end
			end
			if pl[i].alive == 1 then
				if getShaman(i) ~= nil then
					--process stun sprite and cdr
					if pl[i].stun ~= 0 then
						pl[i].stun = pl[i].stun - 1
						local s = createThing(T_EFFECT,M_EFFECT_LIGHTNING_STRAND  ,TRIBE_NEUTRAL,getShaman(i).Pos.D3,false,false)
						s.Pos.D3.Ypos = getShaman(i).Pos.D3.Ypos + 128
						s.u.Effect.Duration = 3
						getShaman(i).DrawInfo.DrawNum = 338--(333,336)
					else
						getShaman(i).Flags = DisableFlag(getShaman(i).Flags, TF_NO_MOVE_PROCESS)
					end
					--show dynamite sprite
					if pl[i].dynamite == 1 then
						local f = createThing(T_EFFECT,60 ,TRIBE_NEUTRAL,getShaman(i).Pos.D3,false,false)
						set_thing_draw_info(f,TDI_SPRITE_F8_D1_ALPHA, 2133)
						f.DrawInfo.Alpha = -16
						f.Pos.D3.Ypos = getShaman(i).Pos.D3.Ypos + 128 + 64
						f.u.Effect.Duration = 2
					end
					--spreading dynamite
					for o = 0,7,1 do
						if getShaman(o) ~= nil then
							if o ~= i then
								if getShaman(o).Pos.D3.Ypos < 256 and getShaman(i).Pos.D3.Ypos < 256 then
									--if 1 shaman has bomb, pass the bomb
									if dynamitedelay == 0 and get_world_dist_xz(getShaman(i).Pos.D2,getShaman(o).Pos.D2) < 300 then
										if pl[i].dynamite == 1 then
											pl[o].dynamite = 1
											pl[i].dynamite = 0
											dynamitedelay = 12*2
											set_player_can_cast(M_SPELL_INSECT_PLAGUE,i)
											set_player_cannot_cast(M_SPELL_INSECT_PLAGUE,o)
											_gsi.ThisLevelInfo.PlayerThings[i].SpellsNotCharging = DisableFlag(_gsi.ThisLevelInfo.PlayerThings[i].SpellsNotCharging, (1 << (throwStone - 1)))
											queue_sound_event(getShaman(i),SND_EVENT_SPELL_CLICK, SEF_FIXED_VARS)
										elseif pl[o].dynamite == 1 then
											pl[o].dynamite = 0
											pl[i].dynamite = 1
											dynamitedelay = 12*2
											set_player_can_cast(M_SPELL_INSECT_PLAGUE,o)
											set_player_cannot_cast(M_SPELL_INSECT_PLAGUE,i)
											_gsi.ThisLevelInfo.PlayerThings[o].SpellsNotCharging = DisableFlag(_gsi.ThisLevelInfo.PlayerThings[o].SpellsNotCharging, (1 << (throwStone - 1)))
											queue_sound_event(getShaman(i),SND_EVENT_SPELL_CLICK, SEF_FIXED_VARS)
										end
									end
								end
							end
						end
					end
				end
			end
		end
		--process round
		if bombTimer > 0 then
			bombTimer = bombTimer - 1
		elseif bombTimer == 0 then
			--process bombTimer ending
			for i = 0,7,1 do
				if pl[i].alive == 1 then
					if pl[i].dynamite == 1 then
						if getShaman(i) ~= nil then
							getShaman(i).Flags = DisableFlag(getShaman(i).Flags, TF_NO_MOVE_PROCESS)
							if i < 4 then team2Score = team2Score+1 else team1Score = team1Score+1 end
							createThing(T_EFFECT,M_EFFECT_ROCK_EXPLOSION, 8, getShaman(i).Pos.D3,false,false)
							queue_sound_event(nil, SND_EVENT_BLDG_MENU_POPUP, SEF_FIXED_VARS)
							local blood = {2109,2110,2111,2112}
							local rdm = blood[math.random(#blood)]
							local ss = createThing(T_EFFECT,60,8,getShaman(i).Pos.D3,false,false)
							set_thing_draw_info(ss,TDI_SPRITE_F1_D1, rdm)
							ss.u.Effect.Duration = -1
							ss.DrawInfo.Alpha = -16
							damage_person(getShaman(i), TRIBE_NEUTRAL, 20000, 1)
							--add death visual
							local Dsprite = 2133
							--if pl[i].ldb ~= 8 then
								--Dsprite = 2083 + pl[i].ldb
							--end
							local Dname = ""
							--if Dsprite ~= 24 then
								--Dname = pl[pl[i].ldb].name
							--end
							local Dname2 = pl[i].name
							table.insert(deaths,{Dname,Dname2,Dsprite,2083+i,12*7})
						end
						pl[i].alive = 0
						pl[i].dynamite = 0
					end
				end
			end
			bombTimer = -1
			stagepause = 12*5
		end
		--dynamite delay timers going down (2 seconds)
		--(this means after giving dynamite to a player, 2 seconds must pass before the next player can give it again, to avoid fast loops/transitions of dynamite)
		if dynamitedelay >= 1 then
			dynamitedelay = dynamitedelay - 1
		elseif dynamitedelay < 0 then
			dynamitedelay = 0
		end
		--win by pts
		if team1Score == 8 or team2Score == 8 then
			if team1Score == 8 and team2Score == 8 then
				log_msg(8,"The game has ended in a tie, with both teams reaching the maximum score!")
				timer = -1
				win = 1
				_gnsi.GameParams.Flags2 = _gnsi.GameParams.Flags2 & ~GPF2_GAME_NO_WIN
				_gnsi.GameParams.Flags3 = _gnsi.GameParams.Flags3 & ~GPF3_NO_GAME_OVER_PROCESS
				for i = 0,7 do
					if getShaman(i) == nil then
						createThing(T_PERSON,M_PERSON_MEDICINE_MAN,i,pl[i].cor,false,false)
						centre_coord3d_on_block(getShaman(i).Pos.D3)
					end
					gns.Flags = gns.Flags | GNS_LEVEL_COMPLETE
				end
			else
				win = 1
				timer = -1
				_gnsi.GameParams.Flags2 = _gnsi.GameParams.Flags2 & ~GPF2_GAME_NO_WIN
				_gnsi.GameParams.Flags3 = _gnsi.GameParams.Flags3 & ~GPF3_NO_GAME_OVER_PROCESS
				if team1Score > team2Score then
					log_msg(8,"The game has ended. Blue team is victorious!")
					for i = 4,7 do
						SET_NO_REINC(i)
						ProcessGlobalSpecialList(i, PEOPLELIST, function(t)
							damage_person(t, 8, 20000, TRUE)
							return true
						end)
						gns.Flags = gns.Flags | GNS_LEVEL_FAILED
					end
					for i = 0,3 do
						if getShaman(i) == nil then
							createThing(T_PERSON,M_PERSON_MEDICINE_MAN,i,pl[i].cor,false,false)
							centre_coord3d_on_block(getShaman(i).Pos.D3)
						end
						gns.Flags = gns.Flags | GNS_LEVEL_COMPLETE
					end
				else
					log_msg(8,"The game has ended. Orange team is victorious!")
					for i = 0,3 do
						SET_NO_REINC(i)
						ProcessGlobalSpecialList(i, PEOPLELIST, function(t)
							damage_person(t, 8, 20000, TRUE)
							return true
						end)
						gns.Flags = gns.Flags | GNS_LEVEL_FAILED
					end
					for i = 4,7 do
						if getShaman(i) == nil then
							createThing(T_PERSON,M_PERSON_MEDICINE_MAN,i,pl[i].cor,false,false)
							centre_coord3d_on_block(getShaman(i).Pos.D3)
						end
						gns.Flags = gns.Flags | GNS_LEVEL_COMPLETE
					end
				end
			end
		end
		if timer > 0 then
			timer = timer -1
		elseif timer == 0 then
			if team1Score ~= team2Score then
				win = 1
				timer = -1
				_gnsi.GameParams.Flags2 = _gnsi.GameParams.Flags2 & ~GPF2_GAME_NO_WIN
				_gnsi.GameParams.Flags3 = _gnsi.GameParams.Flags3 & ~GPF3_NO_GAME_OVER_PROCESS
				if team1Score > team2Score then
					log_msg(8,"The game has ended. Blue team is victorious!")
					for i = 4,7 do
						SET_NO_REINC(i)
						ProcessGlobalSpecialList(i, PEOPLELIST, function(t)
							damage_person(t, 8, 20000, TRUE)
							return true
						end)
						gns.Flags = gns.Flags | GNS_LEVEL_FAILED
					end
					for i = 0,3 do
						if getShaman(i) == nil then
							createThing(T_PERSON,M_PERSON_MEDICINE_MAN,i,pl[i].cor,false,false)
							centre_coord3d_on_block(getShaman(i).Pos.D3)
						end
						gns.Flags = gns.Flags | GNS_LEVEL_COMPLETE
					end
				else
					log_msg(8,"The game has ended. Orange team is victorious!")
					for i = 0,3 do
						SET_NO_REINC(i)
						ProcessGlobalSpecialList(i, PEOPLELIST, function(t)
							damage_person(t, 8, 20000, TRUE)
							return true
						end)
						gns.Flags = gns.Flags | GNS_LEVEL_FAILED
					end
					for i = 4,7 do
						if getShaman(i) == nil then
							createThing(T_PERSON,M_PERSON_MEDICINE_MAN,i,pl[i].cor,false,false)
							centre_coord3d_on_block(getShaman(i).Pos.D3)
						end
						gns.Flags = gns.Flags | GNS_LEVEL_COMPLETE
					end
				end
			else
				log_msg(8,"The game is tied. 30 seconds have been added.")
				timer = 12*31
			end
		end
	end
	--draw sparkles on heads
	for i = 0,7 do
		if getShaman(i) ~= nil then
			local smok = createThing(T_EFFECT,M_EFFECT_SMALL_SPARKLE,TRIBE_HOSTBOT,getShaman(i).Pos.D3,false,false)
			smok.DrawInfo.Alpha = pl[i].color ; smok.u.Effect.Duration = 2
			smok.Pos.D3.Ypos = smok.Pos.D3.Ypos + 32
		end
	end
	--exp timer going down
	if exptimer > 0 then
		exptimer = exptimer - 1
	elseif exptimer == 0 then
		exptimer = -1
		win = 0
		bombTimer = 12*15 + 12*math.random(0,30)
		timer = 12+ 12*60*addedTimer
		queue_sound_event(nil,SND_EVENT_FIGHT_ALARM, SEF_FIXED_VARS)
		set_player_cannot_cast(timerUp,0) set_player_cannot_cast(timerDown,0)
		for i = 0,7 do
			if getShaman(i) ~= nil then
				getShaman(i).Flags = DisableFlag(getShaman(i).Flags, TF_STATE_LOCKED)
			end
		end
		local fB = GetRandomPlayerAlive()
		pl[fB].dynamite = 1
		for i = 0,7 do if i ~= fB then set_player_can_cast(M_SPELL_INSECT_PLAGUE,i) end end
		set_correct_gui_menu()
	end
	--reset score if too big
	if team1Score > 8 then team1Score = 8 end
	if team2Score > 8 then team2Score = 8 end
	if team1Score < 0 then team1Score = 0 end
	if team2Score < 0 then team2Score = 0 end
	--deselect shamans before game starts
	if win == -1 or stagepause >= 0 then
		for i = 0,7,1 do
			DESELECT_ALL_PEOPLE(i)
			if win == 0 then
				MOVE_SHAMAN_TO_MARKER(i,i)
			end
		end
	end
	--last damaged by
	if #deaths > 0 then
		for i = 1,#deaths do
			if i <= #deaths then
				if deaths[i][5] > 0 then
					deaths[i][5] = deaths[i][5] - 1
				elseif deaths[i][5] == 0 then
					table.remove(deaths,i)
					--break
				end
			end
		end
	end
end


function OnCreateThing(t)
	--host can rise or lower the game time
	if win == -1 then
		if t.Type == T_SPELL then
			if t.Owner == 0 then
				if t.Model == timerUp then
					_gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[t.Model] = _gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[t.Model] & 240
					_gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[t.Model] = _gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[t.Model] | 2
					addedTimer = addedTimer + 1
					log_msg(8,"The host has set the game to " .. addedTimer .. " minutes")
				elseif t.Model == timerDown then
					_gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[timerDown] = _gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[timerDown] & 240
					_gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[timerDown] = _gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[timerDown] | 2
					addedTimer = addedTimer - 1
					if addedTimer <= 1 then
						addedTimer = 1
						log_msg(8,"The host has set the game to 1 minute")
					else
						log_msg(8,"The host has set the game to " .. addedTimer .. " minutes")
					end
				end
			end
		end
	end
	if (t.Type == T_SPELL) and (t.Model == throwStone) and getShaman(t.Owner) ~= nil then --throw stone
		t.Model = M_SPELL_NONE
		queue_sound_event(nil,SND_EVENT_BLDG_ROTATE, SEF_FIXED_VARS)
		pl[t.Owner].stoneCDR = 8
		pl[t.Owner].stonec3d = CopyC3d(t.Pos.D3)
		local newS = createThing(T_SPELL, M_SPELL_SHIELD, t.Owner, t.Pos.D3, false, false)--this creates the spellcast line between caster and target pos
		local shots = GET_NUM_ONE_OFF_SPELLS(t.Owner,throwStone)
		_gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[throwStone] = _gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[throwStone] & 240
		_gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[throwStone] = _gsi.ThisLevelInfo.PlayerThings[t.Owner].SpellsAvailableOnce[throwStone] | shots-1
	end
end


function OnFrame()
	if _gnsi.PlayerNum >= 0 and pl[_gnsi.PlayerNum].online == 1 then
		local w = ScreenWidth()
		local h = ScreenHeight()
		local guiW = GFGetGuiWidth()
		--local middle = math.floor ((w)/2)
		local middle2 = math.floor((w+guiW)/2)
		local middle3 = math.floor((w-guiW)/2) - 8 - 8 - 16
		local box = math.floor(h/22)
		local box2 = math.floor(h/32)
		
		--score bars
		PopSetFont(3)
		local barLen = middle3
		local barThickness = math.floor(h/32)
		local percent = math.floor((team1Score * 100)/8)
		local barpercent = math.floor((barLen * percent) / 100)
		DrawBox(guiW + 8-1,4-1,barLen+2,barThickness+2,0)
		DrawBox(guiW + 8,4,barLen,barThickness,1)
		DrawBox(guiW + 8,4,barpercent,barThickness,4)
		local scor = "" .. team1Score .. "/8"
		LbDraw_Text(math.floor((barLen/2)+guiW+8-(string_width(tostring(scor))/2)),4+2,tostring(scor),0)
		--
		local percent = math.floor((team2Score * 100)/8)
		local barpercent = math.floor((barLen * percent) / 100)
		DrawBox(w-8-barLen-1,4-1,barLen+2,barThickness+2,0)
		DrawBox(w-8-barLen,4,barLen,barThickness,1)
		DrawBox(w-8-barLen,4,barpercent,barThickness,14)
		local scor = "" .. team2Score .. "/8"
		LbDraw_Text(math.floor(w -8 - (barLen/2) - (string_width(tostring(scor))/2)),4+2,tostring(scor),0)
		
		if win == 0 then
			--speeds
			local str = ((2 ^ 2) + tmi[TMI_PERSON_MEDICINE_MAN].BaseSpeed - (2 ^ 2))/58
			local str2 = tonumber(string.format("%.1f", str))
			LbDraw_Text(guiW+8,h-8-32,"Shamans speed: " .. str2 .. "x",0)
		end
		
		--kills/deaths
		if #deaths > 0 then
			PopSetFont(3)
			local mask = 18
			local maxShow = 12 if #deaths < maxShow then maxShow = #deaths end
			for i = 1,maxShow do
				local str1 = "" .. deaths[i][1]
				local str2 = "" .. deaths[i][2]
				local SstrLen = math.floor(string_width(str1)+string_width(str2))
				local StotalLen = SstrLen + 2 + 2 + 12 + mask + mask + 1 + 1
				local Sstart = math.floor(w-8-StotalLen)
				LbDraw_ScaledSprite(Sstart,math.floor(barThickness+24+(i*18)),get_sprite(0,deaths[i][3]),mask,mask)
				LbDraw_Text(Sstart+1+mask,math.floor(barThickness+24+(i*18)),deaths[i][1],0)
				LbDraw_ScaledSprite(Sstart+1+mask+string_width(str1)+2,math.floor(barThickness+2+24+(i*18)),get_sprite(0,59),12,12)
				LbDraw_Text(Sstart+1+mask+string_width(str1)+2+2+12,math.floor(barThickness+24+(i*18)),deaths[i][2],0)
				LbDraw_ScaledSprite(Sstart+1+mask+string_width(str1)+2+2+12+string_width(str2)+1,math.floor(barThickness+24+(i*18)),get_sprite(0,deaths[i][4]),mask,mask)
			end
		end
		
		if win == 0 then
			--timer countdown
			PopSetFont(9)
			LbDraw_Text(math.floor(middle2-(string_width(tostring(TurnsToClock(math.floor(timer/12)))))/2),32,tostring(TurnsToClock(math.floor(timer/12))),0)
			--tab to read rules
			PopSetFont(11)
			local tab = "Press TAB to read rules"
			DrawBox(1,1,4+string_width(tostring(tab)),4+10,0)
			DrawBox(3,3,string_width(tostring(tab)),10,1)
			LbDraw_Text(3,3,tostring(tab),0)
		elseif win == -1 then
			--RULES timer countdown
			PopSetFont(9)
			LbDraw_Text(math.floor(middle2-(string_width(tostring(TurnsToClock(math.floor(exptimer/12)))))/2),32,tostring(TurnsToClock(math.floor(exptimer/12))),0)
			local txt1 = "The game will start soon"
			local txt2 = "Players can pause and press TAB"
			local txt3 = "to read the rules beforehand"
			LbDraw_Text(math.floor(middle2-string_width(tostring(txt1))/2),32*2,tostring(txt1),0)
			LbDraw_Text(math.floor(middle2-string_width(tostring(txt2))/2),32*3,tostring(txt2),0)
			LbDraw_Text(math.floor(middle2-string_width(tostring(txt3))/2),32*4,tostring(txt3),0)
			--host msg about add or low timer spells
			if _gnsi.PlayerNum == 0 then
				local txt1 = "You (host) can cast one of the 2 spells"
				local txt2 = "to increase or decrease the minigame timer"
				local txt3 = "you have until the 10 seconds end"
				PopSetFont(3)
				local txt4 = "current game time: " .. addedTimer .. " minutes."
				PopSetFont(9)
				LbDraw_Text(math.floor(middle2-string_width(tostring(txt1))/2),math.floor(h-(32*5)),tostring(txt1),0)
				LbDraw_Text(math.floor(middle2-string_width(tostring(txt2))/2),math.floor(h-(32*4)),tostring(txt2),0)
				LbDraw_Text(math.floor(middle2-string_width(tostring(txt3))/2),math.floor(h-(32*3)),tostring(txt3),0)
				PopSetFont(1)
				LbDraw_Text(math.floor(middle2-string_width(tostring(txt4))/2),math.floor(h-(32*2)),tostring(txt4),0)
			end
		end
	end
end


------------------------------------------------------------------------------------------
--Rules TAB
import(Module_Helpers)
local g_DrawMenu = false
function OnKeyDown(key)
    if (key == LB_KEY_TAB) then
        g_DrawMenu = not g_DrawMenu
    end
end
function OnImGuiFrame()
    if (g_DrawMenu) then
		imgui.Begin('Rules:', nil, ImGuiWindowFlags_AlwaysAutoResize)

		imgui.TextUnformatted("Hot Potato MiniGame:")
	   	imgui.NextColumn()
		imgui.TextUnformatted("")
		imgui.NextColumn()
		imgui.TextUnformatted("A random shaman is assigned a bomb. Touching the shaman with the bomb will pass it (including allies)")
	   	imgui.NextColumn()
		imgui.TextUnformatted("After X seconds, the bomb explodes. Whoever has it loses 1 point for his team")
	   	imgui.NextColumn()
		imgui.TextUnformatted("")
		imgui.NextColumn()
		imgui.TextUnformatted("There is a spell ('thow stone') that, when it hits a target, stuns them for 3-5 seconds")
	   	imgui.NextColumn()
		imgui.TextUnformatted("Whoever has the bomb does not have this spell")
	   	imgui.NextColumn()
		imgui.TextUnformatted("The other teammates must stun enemies, making it easier for the bomb holder to pass it")
	   	imgui.NextColumn()
		imgui.TextUnformatted("* Shamans will have random speeds on each round (all shamans have the same speed) *")
		imgui.NextColumn()
		imgui.TextUnformatted("* No one knows when the bomb will explode. It can be anytime between (15-45s) *")
	   	imgui.NextColumn()
		imgui.TextUnformatted("* Only in the last 5 seconds an indicator will show above the bomb *")
	   	imgui.NextColumn()
		imgui.TextUnformatted("* That's why you always want to pass the bomb asap - you never know it will explode until it's too late *")
	   	imgui.NextColumn()
		imgui.TextUnformatted("")
		imgui.NextColumn()
		imgui.TextUnformatted("First team to reach the points objective is victorious!")
	   	imgui.NextColumn()
		imgui.TextUnformatted("Or the game ends after 8 minutes (whoever has most points wins).")
		imgui.NextColumn()
		imgui.TextUnformatted("")
	   	imgui.NextColumn()
		imgui.TextUnformatted("Hotkeys:")
		imgui.NextColumn()
		imgui.TextUnformatted("THROW STONE - swarm")
		imgui.NextColumn()
		
		imgui.End()
	end
end

function OnSoundEvent(t_thing, event, flags) 
	if (event == SND_EVENT_INFO_DROP) or (event == SND_EVENT_INFO_BOUNCE) or (event == SND_EVENT_SHAMAN_DIE) or (event == SND_EVENT_ESHAMAN_DIE) 
	or event == SND_EVENT_SHAM_INSECT  or event == SND_EVENT_SSHAM_INSECT or event == SND_EVENT_SHAM_SHIELD or event == SND_EVENT_ESHAM_SHIELD then
		return 1
	end
end

--surround arena with stone heads
ProcessGlobalTypeList(T_SCENERY,function(t)
	if t.Model < 10 then
		set_thing_draw_info(t,TDI_SPRITE_F1_D1, 687) 
	end
return true end)

--legendary tree productions ; a tom hanks game
db = createThing(T_EFFECT,M_EFFECT_FLY_THINGUMMY,8,coord_to_c3d(34,36),false,false)
db.u.Effect.Duration = -1 --db.Pos.D3.Ypos = 1024
centre_coord3d_on_block(db.Pos.D3)
set_thing_draw_info(db,TDI_SPRITE_F1_D1, 2122)