-- Every playable mini-round uses the remaining shared tournament budget. -- The regular room engine caps its individual timer at 600 seconds; keeping -- that deadline would cut a longer shared budget short. Reuse the persisted -- budget so polling and transitions never extend the tournament round. create or replace function public.tournament_room_tick(p_tournament uuid,p_room uuid) returns void language plpgsql security invoker set search_path='' as $$ declare t public.tournaments; room public.multiplayer_rooms; budget timestamptz; first_deadline timestamptz; i integer; begin select * into t from public.tournaments where id=p_tournament; if t.timer_mode='perMini' then perform public.multiplayer_tick(p_room); return; end if; select deadline into budget from public.tournament_rounds where room_id=p_room; if budget is null then select deadline into first_deadline from public.multiplayer_rounds where room_id=p_room and round_number=0; if first_deadline is not null then budget:=first_deadline-make_interval(secs=>(t.difficulty_settings->>'seconds')::integer)+make_interval(secs=>t.round_time_seconds); update public.tournament_rounds set deadline=budget where room_id=p_room; end if; end if; if budget is not null and budget<=clock_timestamp() then -- Finish every remaining mini round now, without results/loading delays. for i in 0..4 loop select * into room from public.multiplayer_rooms where id=p_room for update; exit when room.status in('finished','closed'); if room.status='results' then update public.multiplayer_rooms set current_round=current_round+1,status='playing',transition_at=null where id=p_room; else update public.multiplayer_rooms set status='playing',transition_at=null where id=p_room; end if; update public.multiplayer_rounds mr set deadline=budget where mr.room_id=p_room and mr.round_number=(select current_round from public.multiplayer_rooms where id=p_room); perform public.multiplayer_tick(p_room); end loop; return; end if; if budget is not null then update public.multiplayer_rounds mr set deadline=budget where mr.room_id=p_room and mr.round_number=(select current_round from public.multiplayer_rooms where id=p_room) and mr.deadline is not null; end if; perform public.multiplayer_tick(p_room); if budget is null then select deadline into first_deadline from public.multiplayer_rounds where room_id=p_room and round_number=0; if first_deadline is not null then budget:=first_deadline-make_interval(secs=>(t.difficulty_settings->>'seconds')::integer)+make_interval(secs=>t.round_time_seconds); update public.tournament_rounds set deadline=budget where room_id=p_room; end if; end if; if budget is not null then update public.multiplayer_rounds mr set deadline=budget where mr.room_id=p_room and mr.round_number=(select current_round from public.multiplayer_rooms where id=p_room) and mr.deadline is not null; end if; end; $$; notify pgrst,'reload schema';