2020-09-29 19:40:17 +02:00
|
|
|
extends Node
|
|
|
|
class_name Level
|
|
|
|
|
|
|
|
var slug
|
2020-10-12 20:09:51 +02:00
|
|
|
var title
|
2020-09-29 19:40:17 +02:00
|
|
|
var description
|
|
|
|
var congrats
|
2020-10-27 12:16:33 +01:00
|
|
|
var cards
|
2020-09-30 21:36:11 +02:00
|
|
|
var repos = {}
|
2020-09-29 20:01:25 +02:00
|
|
|
|
2020-09-29 19:40:17 +02:00
|
|
|
# The path is an outer path.
|
|
|
|
func load(path):
|
|
|
|
var parts = path.split("/")
|
|
|
|
slug = parts[parts.size()-1]
|
|
|
|
|
2020-09-30 18:10:05 +02:00
|
|
|
var dir = Directory.new()
|
2020-10-06 18:53:31 +02:00
|
|
|
if dir.file_exists(path):
|
2020-09-30 18:10:05 +02:00
|
|
|
# This is a new-style level.
|
|
|
|
var config = helpers.parse(path)
|
|
|
|
|
2020-10-12 20:09:51 +02:00
|
|
|
title = config.get("title", slug)
|
2020-09-30 18:10:05 +02:00
|
|
|
description = config.get("description", "(no description)")
|
2020-10-29 15:55:10 +01:00
|
|
|
congrats = config.get("congrats", "Good job, you solved the level!\n\nFeel free to try a few more things or click 'Next level'.")
|
2020-11-09 20:45:39 +01:00
|
|
|
cards = Array(config.get("cards", "").split(" "))
|
|
|
|
if cards == [""]:
|
|
|
|
cards = []
|
2020-09-30 21:36:11 +02:00
|
|
|
|
|
|
|
var keys = config.keys()
|
|
|
|
var repo_setups = []
|
|
|
|
for k in keys:
|
|
|
|
if k.begins_with("setup"):
|
|
|
|
repo_setups.push_back(k)
|
|
|
|
var repo_wins = []
|
|
|
|
for k in keys:
|
|
|
|
if k.begins_with("win"):
|
|
|
|
repo_wins.push_back(k)
|
|
|
|
|
|
|
|
for k in repo_setups:
|
|
|
|
var repo
|
2020-12-22 12:13:40 +01:00
|
|
|
if " " in k: # [setup yours]
|
2020-09-30 21:36:11 +02:00
|
|
|
repo = Array(k.split(" "))[1]
|
|
|
|
else:
|
|
|
|
repo = "yours"
|
|
|
|
if not repos.has(repo):
|
|
|
|
repos[repo] = LevelRepo.new()
|
|
|
|
repos[repo].setup_commands = config[k]
|
|
|
|
|
|
|
|
for k in repo_wins:
|
|
|
|
var repo
|
|
|
|
if " " in k:
|
|
|
|
repo = Array(k.split(" "))[1]
|
|
|
|
else:
|
|
|
|
repo = "yours"
|
2020-12-22 12:13:40 +01:00
|
|
|
|
|
|
|
var description = "Goal"
|
|
|
|
for line in Array(config[k].split("\n")):
|
|
|
|
if line.length() > 0 and line[0] == "#":
|
|
|
|
description = line.substr(1)
|
|
|
|
else:
|
|
|
|
if not repos[repo].win_conditions.has(description):
|
|
|
|
repos[repo].win_conditions[description] = ""
|
|
|
|
repos[repo].win_conditions[description] += line+"\n"
|
|
|
|
|
|
|
|
# for desc in repos[repo].win_conditions:
|
|
|
|
# print("Desc: " + desc)
|
|
|
|
# print("Commands: " + repos[repo].win_conditions[desc])
|
2020-09-30 18:10:05 +02:00
|
|
|
else:
|
|
|
|
helpers.crash("Level %s does not exist." % path)
|
|
|
|
|
2020-09-30 21:36:11 +02:00
|
|
|
for repo in repos:
|
2020-10-26 19:56:52 +01:00
|
|
|
repos[repo].path = game.tmp_prefix+"repos/%s/" % repo
|
2020-09-30 21:36:11 +02:00
|
|
|
repos[repo].slug = repo
|
|
|
|
|
2020-09-29 19:40:17 +02:00
|
|
|
# Surround all lines indented with four spaces with [code] tags.
|
|
|
|
var monospace_regex = RegEx.new()
|
2020-10-06 10:38:31 +02:00
|
|
|
monospace_regex.compile("\\n ([^\\n]*)")
|
|
|
|
description = monospace_regex.sub(description, "\n [code]$1[/code]", true)
|
2020-09-29 19:50:58 +02:00
|
|
|
|
|
|
|
func construct():
|
2020-09-30 21:36:11 +02:00
|
|
|
for r in repos:
|
|
|
|
var repo = repos[r]
|
|
|
|
# We're actually destroying stuff here.
|
|
|
|
# Make sure that active_repository is in a temporary directory.
|
|
|
|
helpers.careful_delete(repo.path)
|
|
|
|
|
2020-10-06 16:50:31 +02:00
|
|
|
game.global_shell.run("mkdir '%s'" % repo.path)
|
2020-09-30 21:36:11 +02:00
|
|
|
game.global_shell.cd(repo.path)
|
|
|
|
game.global_shell.run("git init")
|
2020-10-30 13:02:34 +01:00
|
|
|
game.global_shell.run("git symbolic-ref HEAD refs/heads/main")
|
2020-09-30 21:36:11 +02:00
|
|
|
|
|
|
|
# Add other repos as remotes.
|
|
|
|
for r2 in repos:
|
|
|
|
if r == r2:
|
|
|
|
continue
|
|
|
|
game.global_shell.run("git remote add %s %s" % [r2, repos[r2].path])
|
|
|
|
|
|
|
|
# Allow receiving a push of the checked-out branch.
|
|
|
|
game.global_shell.run("git config receive.denyCurrentBranch ignore")
|
|
|
|
|
|
|
|
for r in repos:
|
|
|
|
var repo = repos[r]
|
|
|
|
game.global_shell.cd(repo.path)
|
|
|
|
game.global_shell.run(repo.setup_commands)
|
2020-09-29 20:01:25 +02:00
|
|
|
|
|
|
|
func check_win():
|
2020-12-22 12:44:07 +01:00
|
|
|
var win_states = {}
|
2020-09-30 21:36:11 +02:00
|
|
|
for r in repos:
|
|
|
|
var repo = repos[r]
|
2020-12-22 12:13:40 +01:00
|
|
|
if repo.win_conditions.size() > 0:
|
2020-09-30 21:36:11 +02:00
|
|
|
game.global_shell.cd(repo.path)
|
2020-12-22 12:13:40 +01:00
|
|
|
for description in repo.win_conditions:
|
|
|
|
var commands = repo.win_conditions[description]
|
2020-12-22 12:44:07 +01:00
|
|
|
var won = game.global_shell.run("function win { %s\n}; win 2>/dev/null >/dev/null && echo yes || echo no" % commands) == "yes\n"
|
|
|
|
win_states[description] = won
|
|
|
|
return win_states
|