예제 #1
0
def read_damage_resource_info(source: BinarySource) -> Dict:
    return {
        "index": source.read_byte(),
        "long_name": source.read_string(),
        "short_name": source.read_string(),
        "reductions": read_damage_reductions(source),
    }
예제 #2
0
def read_individual_requirement(source: BinarySource) -> Dict:
    return {
        "requirement_type": source.read_byte(),
        "requirement_index": source.read_byte(),
        "amount": source.read_short(),
        "negate": source.read_bool(),
    }
예제 #3
0
 def read_dock_weakness(_source: BinarySource) -> Dict:
     return {
         "index": _source.read_byte(),
         "name": _source.read_string(),
         "is_blast_door": _source.read_bool(),
         "requirement_set": read_requirement_set(_source),
     }
예제 #4
0
def test_read_a():
    b = io.BytesIO(b"\x05aaax\x00?\x80\x00\x00TP\x06@")  # type: BinaryIO
    source = BinarySource(b)

    assert source.read_byte() == 5
    assert source.read_string() == "aaax"
    assert source.read_float() == 1
    source.skip(1)
    assert source.read_bool()
    assert source.read_short() == 1600
예제 #5
0
def decode(binary_io: BinaryIO, extra_io: TextIO) -> Dict:
    if binary_io.read(4) != b"Req.":
        raise Exception("Invalid file format.")

    source = BinarySource(binary_io)
    extra = json.load(extra_io)

    format_version = source.read_uint()
    if format_version != current_format_version:
        raise Exception("Unsupported format version: {}, expected {}".format(
            format_version, current_format_version))

    game = source.read_byte()
    game_name = source.read_string()

    items = read_resource_info_array(source)
    events = read_resource_info_array(source)
    tricks = read_resource_info_array(source)
    damage = read_damage_resource_info_array(source)
    versions = read_resource_info_array(source)
    misc = read_resource_info_array(source)
    difficulty = read_resource_info_array(source)

    dock_weakness_database = read_dock_weakness_database(source)
    worlds = read_world_list(source)

    return {
        "game": game,
        "game_name": game_name,
        "resource_database": {
            "items": items,
            "events": events,
            "tricks": tricks,
            "damage": damage,
            "versions": versions,
            "misc": misc,
            "difficulty": difficulty,
        },
        "starting_location": extra["starting_location"],
        "initial_states": extra["initial_states"],
        "victory_condition": extra["victory_condition"],
        "pickup_database": extra["pickup_database"],
        "dock_weakness_database": dock_weakness_database,
        "worlds": worlds,
    }
예제 #6
0
def read_area(source: BinarySource) -> Dict:
    name = source.read_string()
    asset_id = source.read_uint()
    node_count = source.read_byte()
    default_node_index = source.read_byte()

    nodes = [read_node(source) for _ in range(node_count)]

    for origin in nodes:
        origin["connections"] = {}
        for target in nodes:
            if origin != target:
                requirement_set = read_requirement_set(source)
                if requirement_set:
                    origin["connections"][target["name"]] = requirement_set

    return {
        "name": name,
        "asset_id": asset_id,
        "default_node_index": default_node_index,
        "nodes": nodes
    }
예제 #7
0
def read_resource_info(source: BinarySource) -> Dict:
    return {
        "index": source.read_byte(),
        "long_name": source.read_string(),
        "short_name": source.read_string(),
    }
예제 #8
0
def read_damage_reduction(source: BinarySource) -> Dict:
    return {
        "index": source.read_byte(),
        "multiplier": source.read_float(),
    }
예제 #9
0
def read_world(source: BinarySource) -> Dict:
    return {
        "name": source.read_string(),
        "asset_id": source.read_uint(),
        "areas": read_area_list(source),
    }
예제 #10
0
def read_array(source: BinarySource,
               item_reader: Callable[[BinarySource], X]) -> List[X]:
    count = source.read_byte()
    return [item_reader(source) for _ in range(count)]
예제 #11
0
def read_node(source: BinarySource) -> Dict:
    node = {
        "name": source.read_string(),
        "heal": source.read_bool(),
        "node_type": source.read_byte(),
    }
    node_type = node["node_type"]

    if node_type == 0:
        pass

    elif node_type == 1:
        node["dock_index"] = source.read_byte()
        node["connected_area_asset_id"] = source.read_uint()
        node["connected_dock_index"] = source.read_byte()
        node["dock_type"] = source.read_byte()
        node["dock_weakness_index"] = source.read_byte()
        source.skip(3)

    elif node_type == 2:
        node["pickup_index"] = source.read_byte()

    elif node_type == 3:
        node["destination_world_asset_id"] = source.read_uint()
        node["destination_area_asset_id"] = source.read_uint()
        node["teleporter_instance_id"] = source.read_uint()

    elif node_type == 4:
        node["event_index"] = source.read_byte()

    else:
        raise Exception("Unknown node type: {}".format(node_type))

    return node