Advertisement
FocusedWolf

EFT: Clock

Jul 26th, 2023 (edited)
1,056
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.53 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. # Version 37 - A tarkov reddit moderator permanently banned me for saying this so i feel obligated to repost it here because i hate censorship: "Don't play Arenas. That's the sink for autist cheaters. Every game has someone that walks around like a bot with a crosshair locked on your forehead".
  4.  
  5. # POSTED ONLINE: https://pastebin.com/BZV5c4a6
  6.  
  7. # SOURCE: https://tarkov-time.adam.id.au/
  8. # SOURCE: https://www.reddit.com/r/EscapefromTarkov/comments/u89ccn/i_made_a_physical_eft_clock_so_i_can_tell_when/i5kg22h/
  9. # SOURCE: https://escapefromtarkov.fandom.com/wiki/How_to_Play_Guide_for_Escape_from_Tarkov#IRL_time_vs_EFT_time
  10. # SOURCE: https://www.reddit.com/r/EscapefromTarkov/comments/ur05bc/at_what_time_of_the_raid_is_it_the_most_dark/
  11.  
  12. # -----
  13.  
  14. # Added text to prevent emoji replacement which tend to be smaller.
  15. CULTIST = '~&' # Cultist with a poison knife.
  16. #  CULTIST = "🗡\uFE0E"
  17. #  CULTIST = "🥷"
  18. #  CULTIST = "⛧\uFE0E"
  19. CULTIST = "🕯\uFE0E" # Only Windows 11 terminal can show this emoji.
  20.  
  21. LEFT_ARROW = '<'
  22. LEFT_ARROW = "◀"
  23.  
  24. RIGHT_ARROW = '>'
  25. RIGHT_ARROW = "▶"
  26.  
  27. # -----
  28.  
  29. PURPLE = '\033[38;2;177;72;198m' # Mingw64 purple.
  30. #  PURPLE = '\033[38;2;128;0;128m' # True purple.
  31. #  PURPLE = '\033[38;2;255;0;255m' # Brighter.
  32.  
  33. BLACK = '\033[30m'
  34. RED = '\033[31m'
  35. GREEN = '\033[32m'
  36. YELLOW = '\033[33m'
  37. BLUE = '\033[34m'
  38. MAGENTA = '\033[35m'
  39. CYAN = '\033[36m'
  40. WHITE = '\033[37m'
  41. BRIGHT_BLACK = '\033[90m'
  42. BRIGHT_RED = '\033[91m'
  43. BRIGHT_GREEN = '\033[92m'
  44. BRIGHT_YELLOW = '\033[93m'
  45. BRIGHT_BLUE = '\033[94m'
  46. BRIGHT_MAGENTA = '\033[95m'
  47. BRIGHT_CYAN = '\033[96m'
  48. BRIGHT_WHITE = '\033[97m'
  49. RESET = '\033[0m'
  50. BOLD = '\033[1m'
  51. HALF_BRIGHT = '\033[2m'
  52. ITALIC = '\033[3m'
  53. UNDERLINE = '\033[4m'
  54. REVERSED = '\033[7m'
  55.  
  56. # -----
  57.  
  58. DAY_BRIGHT = BRIGHT_YELLOW
  59. DAY_MORB = YELLOW
  60. NIGHT = BRIGHT_BLACK
  61. UI_CHEVRON = RED
  62. UI_CULTIST = RED
  63. UI_ETA = BRIGHT_WHITE #BRIGHT_CYAN
  64. UI_LABELS = CYAN
  65.  
  66. DAY_BRIGHT = WHITE
  67. DAY_MORB = YELLOW
  68. NIGHT = BRIGHT_BLACK
  69. UI_CHEVRON = RED
  70. UI_CULTIST = PURPLE #BRIGHT_MAGENTA
  71. UI_ETA = CYAN
  72. UI_LABELS = BRIGHT_GREEN #RED #BRIGHT_MAGENTA
  73.  
  74. #
  75. #  DAY_BRIGHT = WHITE
  76. #  DAY_MORB = YELLOW
  77. #  NIGHT = BRIGHT_BLACK
  78. #  UI_CHEVRON = RED
  79. #  UI_CULTIST = RED
  80. #  UI_ETA = RED
  81. #  UI_LABELS = RED#MAGENTA #BRIGHT_MAGENTA #BRIGHT_GREEN
  82.  
  83. # -----
  84.  
  85. #  DAY_BRIGHT = BOLD + BRIGHT_CYAN
  86. #  DAY_MORB = BOLD + BRIGHT_BLUE
  87. #  NIGHT = BOLD + BRIGHT_GREEN
  88. #  UI_CHEVRON = BOLD + RED
  89. #  UI_ETA = BOLD + BRIGHT_BLACK
  90. #  UI_LABELS = BOLD + BRIGHT_BLACK
  91.  
  92. # -----
  93.  
  94. import datetime
  95.  
  96. TARKOV_SECONDS_PER_SECOND = 7 # Seven seconds in Tarkov is one second IRL.
  97. CHARLIE_TIMEZONE = datetime.timezone(datetime.timedelta(hours=3)) # Tarkov uses St. Petersburg - MSK (UTC+3) timezone.
  98. TWELVE_HOUR_SHIFT = datetime.timedelta(hours=12) # Right time is +12 hours ahead of left time.
  99. def get_tarkov_time():
  100.     utc_time = datetime.datetime.now(datetime.timezone.utc)
  101.     tarkov_left_time = datetime.datetime.fromtimestamp(utc_time.timestamp() * TARKOV_SECONDS_PER_SECOND, CHARLIE_TIMEZONE)
  102.     tarkov_right_time = tarkov_left_time + TWELVE_HOUR_SHIFT
  103.     return tarkov_left_time, tarkov_right_time
  104.  
  105. def convert_tarkov_timedelta_to_irl(tarkov_time_delta):
  106.     irl_time_delta = tarkov_time_delta / TARKOV_SECONDS_PER_SECOND
  107.     # Zero the microseconds created by the division because this is the easiest way to hide them.
  108.     irl_time_delta_without_microseconds = irl_time_delta - datetime.timedelta(microseconds=irl_time_delta.microseconds)
  109.     return irl_time_delta_without_microseconds
  110.  
  111. # -----
  112.  
  113. TIME_PERIODS = [
  114.     (0,  'Moonrise'),
  115.     (1,  'Low Moon'),
  116.     (2,  'Medium Moon'),
  117.     (3,  'High Moon'),
  118.     (4,  'No Moon'),
  119.     (5,  'Dawn'),
  120.  
  121.     (6,  'Sunrise'),
  122.     (7,  'Morning'),
  123.     (8,  'Early Day'),
  124.     (9,  'Mid Morning'),
  125.     (10, 'Late Morning'),
  126.     (11, 'Pre Noon'),
  127.  
  128.     (12, 'High Noon'),
  129.     (13, 'Post Meridiem'),
  130.     (14, 'Early Afternoon'),
  131.     (15, 'Mid Afternoon'),
  132.     (16, 'Late Afternoon'),
  133.     (17, 'Pre Dusk'),
  134.  
  135.     (18, 'Early Dusk'),
  136.     (19, 'Late Dusk'),
  137.     (20, 'Sunset'),
  138.     (21, 'Twilight'),
  139.     (22, 'Early Night'),
  140.     (23, 'Deep Night'),
  141. ]
  142.  
  143. MAX_TIME_PERIOD_WIDTH = max(len(time_period[1]) for time_period in TIME_PERIODS)
  144. def get_time_period_name(date_time):
  145.     for hour, time_period in sorted(TIME_PERIODS, reverse=True):
  146.         if date_time.hour >= hour:
  147.             return time_period
  148.  
  149. def format_time(date_time):
  150.     return date_time.strftime('%H:%M:%S')
  151.  
  152. def format_hour(date_time):
  153.     return date_time.strftime('%H')
  154.  
  155. def format_eta(time_delta):
  156.     total_seconds = int(time_delta.total_seconds())
  157.     days, remainder = divmod(total_seconds, 86400)
  158.     hours, remainder = divmod(remainder, 3600)
  159.     minutes, seconds = divmod(remainder, 60)
  160.     return f'T-{f"{days:02d}:" if days > 0 else ""}{hours:02d}:{minutes:02d}:{seconds:02d}'
  161.  
  162. # -----
  163.  
  164. def day_night_rotate_eta(date_time):
  165.     if is_bright_daylight(date_time):
  166.         future_time = datetime.time(hour=BRIGHT_DAYLIGHT_END, minute=0, second=0)
  167.     else:
  168.         future_time = datetime.time(hour=BRIGHT_DAYLIGHT_START, minute=0, second=0)
  169.     return eta(date_time, future_time)
  170.  
  171. # The left and right times are 12 hours apart.
  172. DAY_START = 6
  173. DAY_END = DAY_START + 12
  174. def is_day(date_time):
  175.     return DAY_START <= date_time.hour < DAY_END
  176.  
  177. # SOURCE: https://www.reddit.com/r/EscapefromTarkov/comments/7wwbmw/bsg_why_are_there_16_hours_of_daylight_in_this/
  178. DAYLIGHT_END = DAY_START + 16 # Dim daylight end time.
  179. def is_any_daylight(date_time):
  180.     return DAY_START <= date_time.hour < DAYLIGHT_END
  181.  
  182. BRIGHT_DAYLIGHT_START = DAY_START + 2 # Bright daylight start time.
  183. BRIGHT_DAYLIGHT_END = DAY_END + 2 # Sun is setting.
  184. def is_bright_daylight(date_time):
  185.     return BRIGHT_DAYLIGHT_START <= date_time.hour < BRIGHT_DAYLIGHT_END
  186.  
  187. # SOURCE: ["Cultists appear between 22:00 and 7:00"] https://escapefromtarkov.fandom.com/wiki/Cultists
  188. # SOURCE: ["Between the times of 22:00 and 6:00"] https://youtu.be/pwIWGq6QACQ?si=fIPJFb-DrPObOzl_&t=269
  189. # SOURCE: ["So approximately 6:00 by Tarkov time they stand up and go into some place to despawn and just disappear. Their dead bodies do not disappear."] https://www.reddit.com/r/EscapefromTarkov/comments/14kan9b/i_always_was_wonder_how_when_and_does_cultists/
  190. # SOURCE: ["The Boss (Priest) spawns from 11PM to 6AM. After sunrise, the cultists disappear from the map."] https://tarkov.help/en/article/cultists
  191. # SOURCE: ["They absolutely despawn around 5:30 am"] https://www.reddit.com/r/EscapefromTarkov/comments/r14frs/cultist_despawn_at_daylight/
  192. # SOURCE: ["Cultists spawn from 23:00 (11 PM) to 5:00 (5 AM)"] https://www.reddit.com/r/EscapefromTarkov/comments/l69pvx/i_found_the_cultist_priest_on_day_time_woods/gkzxjpb/
  193. # SOURCE: ["I always thought they stopped spawning at 5 am not 7 am...22-5 you are correct."] https://www.reddit.com/r/EscapefromTarkov/comments/wvq6a4/how_do_cultist_spawns_really_work/
  194. # SOURCE: Cultist Spawn Locations: https://escapefromtarkov.fandom.com/wiki/Cultists
  195. #         Customs=1 priest + 4 warriors at scav base (ZB-013 extraction).
  196. #         Woods=1 priest + 4 warriors near their ritual places which are located west of sawmill and also at the dilapidated village in the north.
  197. #         Shoreline= 1 priest + 3 warriors at health resort and(rare)/or north-east of the swamp village.
  198. #         Night Factory=1 priest + 2 warriors.
  199. CULTIST_SPAWN_START = 22
  200. CULTIST_SPAWN_END = 5 # 7 # TODO: The wiki says 7 but a lot of sources say this should be 5, to represent 05:00 - 05:59, with 06:00 being when cultists despawn but need more info.
  201. #  CULTIST_SPAWN_END = 7 # This guy says 7 AM but probably just quoting wiki. https://www.reddit.com/r/EscapefromTarkov/comments/1eq4n55/discussion_cultist_dagger_farming_for_night_sweep/
  202. CULTIST_SPAWN_END = 6 # AI says its between 06:00 and 06:59 and then thats it, they are despawned.
  203. def is_cultist_time(date_time):
  204.     return not (CULTIST_SPAWN_END < date_time.hour < CULTIST_SPAWN_START)
  205.  
  206. def eta(date_time, future_time):
  207.     future_date_time = date_time.replace(hour=future_time.hour, minute=future_time.minute, second=future_time.second)
  208.     if future_date_time < date_time:
  209.         future_date_time += datetime.timedelta(days=1)
  210.     remaining_time_delta = future_date_time - date_time
  211.     return remaining_time_delta, future_date_time
  212.  
  213. def color_hour(string, date_time):
  214.     return color(string, DAY_BRIGHT if is_bright_daylight(date_time) else DAY_MORB if is_any_daylight(date_time) else NIGHT)
  215.  
  216. def color(var, color):
  217.     return color + str(var) + RESET
  218.  
  219. def color_ljust(string, width, fillchar=' '):
  220.     if color_len(string) >= width:
  221.         return string
  222.     return string + fillchar * (width - color_len(string))
  223.  
  224. def color_rjust(string, width, fillchar=' '):
  225.     if color_len(string) >= width:
  226.         return string
  227.     return fillchar * (width - color_len(string)) + string
  228.  
  229. import re
  230. def color_len(string):
  231.     # Remove color codes to measure visible characters.
  232.     return len(re.sub(r'\033\[\d+m', '', string))
  233.  
  234. import os
  235. def clear():
  236.     os.system('cls' if os.name in ('nt', 'dos') else 'clear')
  237.  
  238. import time
  239. def sleep(milliseconds):
  240.     time.sleep(milliseconds / 1000)
  241.  
  242. ALIGN_LEFT = '<'
  243. ALIGN_RIGHT = '>'
  244. ALIGN_CENTER = '^'
  245.  
  246. # -----
  247.  
  248. def main():
  249.     while True:
  250.         clear() # Need to clear before color(...) can be used.
  251.         print()
  252.  
  253.         left_time, right_time = get_tarkov_time()
  254.         left_cultist = color(f'{" " + CULTIST if is_cultist_time(left_time) else ""}', UI_CULTIST)
  255.         right_cultist = color(f'{CULTIST + " " if is_cultist_time(right_time) else ""}', UI_CULTIST)
  256.         left_time_display = color_hour(f'{get_time_period_name(left_time)} {format_time(left_time)}', left_time) + left_cultist
  257.         right_time_display = right_cultist + color_hour(f'{format_time(right_time)} {get_time_period_name(right_time)}', right_time)
  258.  
  259.         day_night_composition = '▛' if is_day(left_time) else '▜'
  260.         bright_daylight_eta, left_day_night_sector_time = day_night_rotate_eta(left_time)
  261.         #  print(f' {color(f" Tarkov Times:", UI_LABELS)} {color("[", UI_LABELS)} {left_time_display} {color("-", UI_LABELS)} {right_time_display} {color("]", UI_LABELS)} {color(day_night_composition, DAY_MORB)} {color(format_eta(convert_tarkov_timedelta_to_irl(bright_daylight_eta)), UI_ETA)}')
  262.         print(f' {color(f" Tarkov Times:", UI_LABELS)} {color("[", UI_LABELS)} {left_time_display} {color("-", UI_LABELS)} {right_time_display} {color("]", UI_LABELS)} {color(day_night_composition, DAY_BRIGHT)} {color(format_eta(convert_tarkov_timedelta_to_irl(bright_daylight_eta)), UI_ETA)}')
  263.  
  264.         # -----
  265.  
  266.         # TODO: commented out because its redundant with cultist-spawn indicators on the vertical times.
  267.         #
  268.         # Print horizontal time-progressbar.
  269.         #  print()
  270.         #  print('  ', end='')
  271.         #  # For [0,24).
  272.         #  for h in range(24):
  273.         #      h_time = datetime.time(hour=h)
  274.         #      if is_cultist_time(h_time):
  275.         #          print(color(f'{CULTIST} ', UI_CULTIST), end='')
  276.         #      else:
  277.         #          print('   ', end='')
  278.         #  print()
  279.         #  print('  ', end='')
  280.         #  # For [0,24).
  281.         #  for h in range(24):
  282.         #      h_time = datetime.time(hour=h)
  283.         #      if h == left_time.hour or h == right_time.hour:
  284.         #          print(color_hour(f'╳╳ ', h_time), end='')
  285.         #          #  print(color_hour(f'◀▶ ', h_time), end='')
  286.         #      else:
  287.         #          print(color_hour(f'██ ', h_time), end='')
  288.         #  print()
  289.         #  print('  ', end='')
  290.         #  # For [0,24).
  291.         #  for h in range(24):
  292.         #      h_time = datetime.time(hour=h)
  293.         #      print(color_hour(h_time.strftime('%H '), h_time), end='')
  294.         #  print()
  295.  
  296.         # -----
  297.  
  298.         # V2 - Added cultist-spawn indicators.
  299.         #
  300.         # Print time-period names while indicating which slot we are in.
  301.         print()
  302.         for h in range(DAY_START, DAY_END):
  303.             h_time = datetime.datetime.now().replace(hour=h, minute=0, second=0)
  304.             if not is_day(left_time):
  305.                 h_time -= TWELVE_HOUR_SHIFT
  306.             left_game_time = color_hour(f'{get_time_period_name(h_time):{ALIGN_RIGHT}{MAX_TIME_PERIOD_WIDTH}} {format_hour(h_time)}', h_time)
  307.             left_cultist = color(f'{CULTIST if is_cultist_time(h_time) else "  "}', UI_CULTIST)
  308.             left_arrow_time = color_hour(f'{LEFT_ARROW if left_time.hour == h_time.hour else " "}', h_time)
  309.             h_time += TWELVE_HOUR_SHIFT
  310.             right_arrow_time = color_hour(f'{RIGHT_ARROW if right_time.hour == h_time.hour else " "}', h_time)
  311.             right_cultist = color(f'{CULTIST if is_cultist_time(h_time) else "  "}', UI_CULTIST)
  312.             right_game_time = color_hour(f'{format_hour(h_time)} {get_time_period_name(h_time)}', h_time)
  313.             on_time = left_time.hour == h or right_time.hour == h
  314.             closest_time_eta = min(eta(left_time, h_time)[0], eta(right_time, h_time)[0])
  315.             irl_time = color(format_eta(convert_tarkov_timedelta_to_irl(closest_time_eta)), UI_ETA)
  316.             print(f' {left_game_time} {left_cultist} {left_arrow_time} {irl_time} {right_arrow_time} {right_cultist} {right_game_time}')
  317.  
  318.         # V1 - Arrows are colored based on the hour.
  319.         #
  320.         # Print time-period names while indicating which slot we are in.
  321.         #  print()
  322.         #  for h in range(DAY_START, DAY_END):
  323.         #      h_time = datetime.datetime.now().replace(hour=h, minute=0, second=0)
  324.         #      if not is_day(left_time):
  325.         #          h_time -= TWELVE_HOUR_SHIFT
  326.         #      left_game_time = color_hour(f'{get_time_period_name(h_time):{ALIGN_RIGHT}{MAX_TIME_PERIOD_WIDTH}} {format_hour(h_time)} {LEFT_ARROW if left_time.hour == h_time.hour else " "}', h_time)
  327.         #      h_time += TWELVE_HOUR_SHIFT
  328.         #      right_game_time = color_hour(f'{RIGHT_ARROW if right_time.hour == h_time.hour else " "} {format_hour(h_time)} {get_time_period_name(h_time)}', h_time)
  329.         #      on_time = left_time.hour == h or right_time.hour == h
  330.         #      closest_time_eta = min(eta(left_time, h_time)[0], eta(right_time, h_time)[0])
  331.         #      irl_time = color(format_eta(convert_tarkov_timedelta_to_irl(closest_time_eta)), UI_ETA)
  332.         #      print(f' {left_game_time} {irl_time} {right_game_time}')
  333.  
  334.         # V0 - Arrows are colored UI_CHEVRON.
  335.         #
  336.         # Print time-period names while indicating which slot we are in.
  337.         #  print()
  338.         #  for h in range(DAY_START, DAY_END):
  339.         #      h_time = datetime.datetime.now().replace(hour=h, minute=0, second=0)
  340.         #      if not is_day(left_time):
  341.         #          h_time -= TWELVE_HOUR_SHIFT
  342.         #      left_game_time = color_hour(f'{get_time_period_name(h_time):{ALIGN_RIGHT}{MAX_TIME_PERIOD_WIDTH}} {format_hour(h_time)}', h_time)
  343.         #      h_time += TWELVE_HOUR_SHIFT
  344.         #      right_game_time = color_hour(f'{format_hour(h_time)} {get_time_period_name(h_time)}', h_time)
  345.         #      on_time = left_time.hour == h or right_time.hour == h
  346.         #      left_arrow = color(LEFT_ARROW if on_time else ' ', UI_CHEVRON)
  347.         #      closest_time_eta = min(eta(left_time, h_time)[0], eta(right_time, h_time)[0])
  348.         #      irl_time = color(format_eta(convert_tarkov_timedelta_to_irl(closest_time_eta)), UI_ETA)
  349.         #      right_arrow = color(RIGHT_ARROW if on_time else ' ', UI_CHEVRON)
  350.         #      print(f' {left_game_time} {left_arrow} {irl_time} {right_arrow} {right_game_time}')
  351.  
  352.         sleep(1000)
  353.  
  354. if __name__ == '__main__':
  355.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement