#MAIN

#time spent in a puzzle set
execute if entity @a[limit=1,tag=inControl] run function bd:game/track_game_time

#10Hz timer
scoreboard players add global oTimer 1
execute if score global oTimer matches 2.. run scoreboard players set global oTimer 0

#2sec timer (or 1.5 sec? I guess I changed my mind)
scoreboard players add global timer2sec 1
execute if score global timer2sec matches 31.. run scoreboard players set global timer2sec 1

#model direction correction
scoreboard players add global dCorrect 1
execute if score global dCorrect matches 6.. run scoreboard players set global dCorrect 0

#moving objects
#-- moving blocks with no gravity get processed first
#-- moving blocks with artificial gravity get processed second
#-- moving blocks with natural gravity get processed third
#-- player gets processed last
execute as @e[tag=!player_char,tag=!can_fall,scores={moveCommitTime=1..}] at @s run function bd:movement/object/_commit_index
execute as @e[tag=!player_char,tag=can_fall,tag=!natural_gravity,scores={moveCommitTime=1..}] at @s run function bd:movement/object/_commit_index
execute as @e[tag=!player_char,tag=can_fall,tag=natural_gravity,scores={moveCommitTime=1..}] at @s run function bd:movement/object/_commit_index
execute as @e[tag=player_char,scores={moveCommitTime=1..}] at @s run function bd:movement/object/_commit_index

#input cooldown
scoreboard players remove @a[scores={inputCooldown=1..}] inputCooldown 1
execute if score global moveCooldown matches 1.. run scoreboard players remove global moveCooldown 1

#tag the current "real" player
tag @a[tag=player] remove player
execute as @a if score @s playerID = global currentPlayer run tag @s add player

#immediately integrate players once they join the world
function bd:join/_tick

#visual effects in puzzle area
function bd:ambient/visual_effects

#effects for players
function bd:eternal_potion_effects

#keep all adventure mode players from jumping off the building
execute as @a[gamemode=adventure,tag=!inControl] at @s run function bd:keep_player_in_bounds

#carrot on a stick
execute as @a at @s run function bd:carrot_on_stick

#input detection
execute as @a[tag=inControl] at @s run function bd:control/get_inputs
execute as @a[tag=inControl] at @s run function bd:control/_control_main

#level changes
execute unless score global currentLevel = global levelEcho run function bd:levels/_load_start
execute if score global levelLoading matches 1.. run function bd:levels/_load

#kill all unwanted item drops
execute as @e[type=item] unless entity @s[nbt={Item:{tag:{Tags:["stay"]}}}] if entity @s[tag=!stay] run kill @s
kill @e[type=experience_orb,tag=!stay]

#ambient sound
execute as @a at @s run function bd:ambient/sound_main
execute if score global beepTime matches 1.. run scoreboard players remove global beepTime 1
execute as @e[limit=1,tag=player_char,type=area_effect_cloud] at @s run function bd:ambient/bulldozer_idle

#record undo?
execute unless score global dontRecordUndo matches 1 if score global recordNextReset matches 1 if score global levelLoading matches 0 if entity @e[limit=1,tag=player_char,tag=player_char] unless entity @e[scores={moveCommitTime=1..}] unless entity @e[limit=1,type=falling_block] unless entity @e[limit=1,type=armor_stand,tag=kill_on_next_move] run function bd:game/record_undo

#win checking
execute unless score global checkForWin matches ..-1 run scoreboard players remove global checkForWin 1
execute if score global checkForWin matches 1 unless score global currentLevel matches 1 unless score global levelLoading matches 1.. run function bd:game/check_for_win

#tutorial messages
execute if score global currentLevel matches 1001..1007 unless score global levelLoading matches 1..34 run function bd:game/tutorial_messages

#failure messages
execute if score global timer2sec matches ..15 if score global hitCone matches 1 run title @a[tag=inControl] actionbar ["",{"text":"You hit a cone! Level failed.","color":"dark_red","bold":true}]
execute if score global timer2sec matches 16.. if score global hitCone matches 1 run title @a[tag=inControl] actionbar ["",{"text":"You hit a cone! Level failed.","color":"red","bold":true}]
execute if score global timer2sec matches ..15 if score global hitCone matches 0 as @e[tag=player_char,type=area_effect_cloud,limit=1] at @s if block ~ ~ ~ light_gray_concrete_powder run title @a[tag=inControl] actionbar ["",{"text":"Stuck! Level failed.","color":"dark_red","bold":true}]
execute if score global timer2sec matches 16.. if score global hitCone matches 0 as @e[tag=player_char,type=area_effect_cloud,limit=1] at @s if block ~ ~ ~ light_gray_concrete_powder run title @a[tag=inControl] actionbar ["",{"text":"Stuck! Level failed.","color":"red","bold":true}]

#lifespan score, applied to entities that are meant to be temporary
scoreboard players remove @e[scores={lifespan=1..}] lifespan 1
execute as @e[type=!player,scores={lifespan=..0}] at @s run tp @s ~ ~-10000 ~
kill @e[type=!player,scores={lifespan=..0}]

#is somebody trying to select a puzzle set to play?
execute if entity @a[x=21,y=58,z=10,dx=12,dy=12,dz=12,gamemode=!spectator] as @a[x=21,y=58,z=10,dx=12,dy=12,dz=12,gamemode=!spectator] run function bd:game/listen_for_puzzle_set_selection

#clear tags and stuff
scoreboard players reset @a carrotInput
tag @a[tag=no_dupe_message] remove no_dupe_message