Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import random
- import binascii
- mountain_width = 1000 # same as in the game
- class Mountain:
- def __init__(self, name, height, treeline, yetiline, encoded_flag):
- self.name = name
- self.height = height
- self.treeline = treeline
- self.yetiline = yetiline
- self.encoded_flag = encoded_flag
- self.treasures = self.GetTreasureLocations()
- def GetTreasureLocations(self):
- """
- Reimplementation of the game's treasure placement:
- - Deterministic per mountain name via crc32(name)
- - 5 treasures at decreasing elevations (down the mountain)
- - Each treasure has a horizontal position (can be out of bounds, later modded)
- """
- locations = {}
- random.seed(binascii.crc32(self.name.encode("utf-8")))
- prev_height = self.height
- prev_horiz = 0
- for _ in range(5):
- e_delta = random.randint(200, 800)
- h_delta = random.randint(int(0 - e_delta / 4), int(e_delta / 4))
- elevation = prev_height - e_delta
- horiz = prev_horiz + h_delta
- locations[elevation] = horiz
- prev_height = elevation
- prev_horiz = horiz
- return locations
- def SetFlag(mountain, treasure_list):
- """
- Exact copy of the game's flag-decoding logic:
- product = (product << 8) ^ treasure_val
- random.seed(product)
- decoded_byte = encoded_flag[i] ^ random.randint(0, 255)
- """
- product = 0
- for treasure_val in treasure_list:
- product = (product << 8) ^ treasure_val
- random.seed(product)
- decoded_chars = []
- for b in mountain.encoded_flag:
- r = random.randint(0, 255)
- decoded_chars.append(chr(b ^ r))
- flag_text = "Flag: %s" % "".join(decoded_chars)
- return flag_text
- # Recreate Mountains as in the decompiled code
- Mountains = [
- Mountain(
- "Mount Snow",
- 3586,
- 3400,
- 2400,
- b"\x90\x00\x1d\xbc\x17b\xed6S\"\xb0<Y\xd6\xce\x169\xae\xe9|\xe2Gs\xb7\xfdy\xcf5\x98",
- ),
- Mountain(
- "Aspen",
- 11211,
- 11000,
- 10000,
- b"U\xd7%x\xbfvj!\xfe\x9d\xb9\xc2\xd1k\x02y\x17\x9dK\x98\xf1\x92\x0f!\xf1\\\xa0\x1b\x0f",
- ),
- Mountain(
- "Whistler",
- 7156,
- 6000,
- 6500,
- b"\x1cN\x13\x1a\x97\xd4\xb2!\xf9\xf6\xd4#\xee\xebh\xecs.\x08M!hr9?\xde\x0c\x86\x02",
- ),
- Mountain(
- "Mount Baker",
- 10781,
- 9000,
- 6000,
- b"\xac\xf9#\xf4T\xf1%h\xbe3FI+h\r\x01V\xee\xc2C\x13\xf3\x97ef\xac\xe3z\x96",
- ),
- Mountain(
- "Mount Norquay",
- 6998,
- 6300,
- 3000,
- b"\x0c\x1c\xad!\xc6,\xec0\x0b+\"\x9f@.\xc8\x13\xadb\x86\xea{\xfeS\xe0S\x85\x90\x03q",
- ),
- Mountain(
- "Mount Erciyes",
- 12848,
- 10000,
- 12000,
- b"n\xad\xb4l^I\xdb\xe1\xd0\x7f\x92\x92\x96\x1bq\xca`PvWg\x85\xb21^\x93F\x1a\xee",
- ),
- Mountain(
- "Dragonmount",
- 16282,
- 15500,
- 16000,
- b"Z\xf9\xdf\x7f_\x02\xd8\x89\x12\xd2\x11p\xb6\x96\x19\x05x))v\xc3\xecv\xf4\xe2\\\x9a\xbe\xb5",
- ),
- ]
- def compute_treasure_list(mountain: Mountain):
- """
- In-game, when you collide with a treasure at:
- - elevation = collided_row[0]
- - column = collided_row_offset (0..mountain_width-1)
- it records: elevation * mountain_width + collided_row_offset
- We reconstruct the SAME values from the deterministic treasure map:
- - elevation is the key in mountain.treasures
- - horizontal index is (horiz % mountain_width)
- """
- treasure_values = []
- # Treasures are generated from top to bottom (highest to lowest elevation),
- # and the player will naturally encounter them in that order.
- # We emulate that ordering explicitly.
- for elevation, horiz in sorted(mountain.treasures.items(), key=lambda kv: kv[0], reverse=True):
- col = horiz % mountain_width
- treasure_val = elevation * mountain_width + col
- treasure_values.append(treasure_val)
- return treasure_values
- def main():
- for mnt in Mountains:
- treasure_list = compute_treasure_list(mnt)
- flag = SetFlag(mnt, treasure_list)
- print(f"Mountain: {mnt.name}")
- print(f" Treasures (elev, horiz_mod):")
- for elevation, horiz in sorted(mnt.treasures.items(), key=lambda kv: kv[0], reverse=True):
- print(f" elevation={elevation}, horiz_mod={horiz % mountain_width}")
- print(f" {flag}")
- print("-" * 60)
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment