DeckConfigParser.gd 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. class_name DeckConfigParser
  2. extends Node
  3. # Эта регулярка ищет одно из двух
  4. # A) rank * suit (знак умножения между словами),
  5. # Б) deck (без знака умножить)
  6. # И определят знак перед этой конструкцией, чтобы дальше "сложить" или "вычесть"
  7. const DECK_FINDER = "(^|(?<sign>\\+|\\-))\\s*(:?(?<rank>\\w+)\\s*\\*\\s*(?<suit>\\w+)|(?<deck>\\w*))"
  8. var _config = {
  9. "ranks": {},
  10. "suits": {},
  11. "decks": {},
  12. }
  13. func init(config_path):
  14. if config_path == "":
  15. print("Empty config path")
  16. return
  17. if not UsefullFunctions.file_exists(config_path):
  18. print("Could't find a config `%s`" % config_path)
  19. return
  20. var cf = ConfigFile.new()
  21. var err = cf.load(config_path)
  22. # 43 - ERR_PARSE_ERROR
  23. if err != OK:
  24. print("ConfigFile.load erro %s" % err)
  25. return
  26. for section in _config:
  27. if not cf.has_section(section): continue
  28. for key in cf.get_section_keys(section):
  29. var str_value = str(cf.get_value(section, key))
  30. if section == "decks":
  31. _config[section][key] = str_value
  32. else:
  33. var ar_value = []
  34. # Вот эта вся лабуда нужна, чтобы из 2..10 сделать массив
  35. # [2, 3, 4, 5, 6, 7, 8, 9, 10]
  36. # Отрицательные тоже прокатаят, например -3..1 станет
  37. # [-3, -2, -1, 0, 1]
  38. # Мб перенести это куда-нибудь
  39. var re = RegEx.new()
  40. re.compile("(\\-?\\d+)\\.\\.(\\d+)")
  41. for v in str_value.split(" "):
  42. var m = re.search(v)
  43. if m:
  44. for i in range(int(m.get_string(1)), int(m.get_string(2)) + 1):
  45. ar_value.append(i)
  46. else:
  47. ar_value.append(v)
  48. _config[section][key] = ar_value
  49. func get_ids(deck_name, i : int = 0):
  50. if i > 10:
  51. print("Infinitive loop yoba")
  52. return []
  53. var cache_key = "DeckConfigParser_" + deck_name
  54. # кеш работает только в игре. как и все автолоады
  55. if not Engine.is_editor_hint() and Cache.has(cache_key):
  56. return Cache.retrieve(cache_key)
  57. if not _config["decks"].has(deck_name):
  58. return []
  59. var deck_params = _config["decks"][deck_name]
  60. var re_deck = RegEx.new()
  61. re_deck.compile(DECK_FINDER)
  62. var card_ids = []
  63. for m in re_deck.search_all(deck_params):
  64. var working_ar = []
  65. var deck = m.get_string("deck")
  66. if deck:
  67. working_ar = get_ids(deck, i + 1)
  68. else:
  69. for r in _config["ranks"][m.get_string("rank")]:
  70. for s in _config["suits"][m.get_string("suit")]:
  71. working_ar.append([r, s])
  72. if m.get_string("sign") == "-":
  73. card_ids = array_subtraction(card_ids, working_ar)
  74. else:
  75. card_ids = array_adding(card_ids, working_ar)
  76. if not Engine.is_editor_hint():
  77. Cache.add(cache_key, card_ids)
  78. return card_ids
  79. # Вообще эти две функции (особенно первая элитная) не особенно нужны,
  80. # а особенно тут, но сделал так для наглядности и единобразия
  81. # В принципе, весь их код можно скопировать выше, а функии удалить
  82. func array_adding(ar1, ar2):
  83. return ar1 + ar2
  84. func array_subtraction(ar1, ar2):
  85. for el in ar2:
  86. ar1.erase(el)
  87. return ar1