class TestEbTextPointer(BaseTestCase): def setup(self): self.pointer = EbTextPointer(size=4) def test_from_block(self): block = Block() block.from_list([0xc0, 0xc1, 0xc2, 0x00, 0xff, 0xff, 0xff, 0x00, 0xef, 0xfe, 0x02, 0x00, 0x01, 0x02, 0x03, 0x01]) self.pointer.from_block(block, 0) assert_equal(self.pointer.address, 0xc2c1c0) self.pointer.from_block(block, 4) assert_equal(self.pointer.address, 0xffffff) assert_raises(InvalidEbTextPointerError, self.pointer.from_block, block, 8) assert_raises(InvalidEbTextPointerError, self.pointer.from_block, block, 12) def test_from_yml_rep(self): self.pointer.from_yml_rep("$c30201") assert_equal(self.pointer.address, 0xc30201) assert_raises(InvalidEbTextPointerError, self.pointer.from_yml_rep, "$070102") assert_raises(InvalidEbTextPointerError, self.pointer.from_yml_rep, "$1000000")
class NpcDoor(GenericDoor): def __init__(self, x=None, y=None, type=DoorType.PERSON, text_address=None): super(NpcDoor, self).__init__(x, y) self.type = type if text_address is None: self.text_pointer = EbTextPointer(size=4) else: self.text_pointer = EbTextPointer(size=4, address=text_address) def from_block(self, block, offset): super(NpcDoor, self).from_block(block, offset) self.type = block[offset + 2] if not DoorType.is_valid(self.type): raise InvalidUserDataError("Door had invalid type of %#x" % self.type) destination_offset = block.read_multi(offset + 3, 2) | 0xF0000 self.text_pointer.from_block(block, destination_offset) def write_to_block(self, block, offset, destination_locations): super(NpcDoor, self).write_to_block(block, offset, destination_locations) block[offset + 2] = self.type with Block() as destination_block: destination_block.from_list([0] * 4) self.text_pointer.to_block(destination_block, 0) self.write_destination_to_block(block, offset, destination_block, destination_locations) return 5 def yml_rep(self): out = super(NpcDoor, self).yml_rep() try: out["Type"] = DoorType.tostring(self.type) except InvalidArgumentError: raise InvalidUserDataError("Door had invalid type of %#x" % self.type) out["Text Pointer"] = self.text_pointer.yml_rep() return out def from_yml_rep(self, yml_rep): super(NpcDoor, self).from_yml_rep(yml_rep) self.type = get_enum_from_user_dict(yml_rep, "Type", DoorType) self.text_pointer.from_yml_rep(get_from_user_dict(yml_rep, "Text Pointer", str))
class SwitchDoor(GenericDoor): def __init__(self, x=None, y=None, flag=None, text_address=None): super(SwitchDoor, self).__init__(x, y) self.flag = flag if text_address is not None: self.text_pointer = EbTextPointer(address=text_address, size=4) else: self.text_pointer = EbTextPointer(size=4) def from_block(self, block, offset): super(SwitchDoor, self).from_block(block, offset) destination_offset = block.read_multi(offset + 3, 2) | 0xF0000 self.flag = block.read_multi(destination_offset, 2) self.text_pointer.from_block(block, destination_offset + 2) def write_to_block(self, block, offset, destination_locations): super(SwitchDoor, self).write_to_block(block, offset, destination_locations) block[offset + 2] = DoorType.SWITCH with Block() as destination_block: destination_block.from_list([0] * 6) destination_block.write_multi(0, self.flag, 2) self.text_pointer.to_block(destination_block, 2) self.write_destination_to_block(block, offset, destination_block, destination_locations) return 5 def yml_rep(self): out = super(SwitchDoor, self).yml_rep() out["Type"] = DoorType.tostring(DoorType.SWITCH) out["Event Flag"] = EbEventFlagTableEntry.to_yml_rep(self.flag) out["Text Pointer"] = self.text_pointer.yml_rep() return out def from_yml_rep(self, yml_rep): super(SwitchDoor, self).from_yml_rep(yml_rep) self.flag = EbEventFlagTableEntry.from_yml_rep(get_from_user_dict(yml_rep, "Event Flag", int)) self.text_pointer.from_yml_rep(get_from_user_dict(yml_rep, "Text Pointer", str))
class Door(GenericDoor): def __init__(self, x=None, y=None, text_address=None, flag=None, destination_x=None, destination_y=None, destination_direction=DestinationDirection.DOWN, destination_style=None): super(Door, self).__init__(x, y) if text_address is not None: self.text_pointer = EbTextPointer(address=text_address, size=4) else: self.text_pointer = EbTextPointer(size=4) self.flag = flag self.destination_x = destination_x self.destination_y = destination_y self.destination_direction = destination_direction self.destination_style = destination_style def from_block(self, block, offset): super(Door, self).from_block(block, offset) destination_offset = block.read_multi(offset + 3, 2) | 0xF0000 self.text_pointer.from_block(block, destination_offset) self.flag = block.read_multi(destination_offset + 4, 2) self.destination_y = block[destination_offset + 6] self.destination_y |= (block[destination_offset + 7] & 0x3f) << 8 self.destination_direction = (block[destination_offset + 7] & 0xc0) >> 6 if not DestinationDirection.is_valid(self.destination_direction): raise InvalidUserDataError("Door had invalid destination direction of %#x" % self.destination_direction) self.destination_x = block.read_multi(destination_offset + 8, 2) self.destination_style = block[destination_offset + 10] def write_to_block(self, block, offset, destination_locations): super(Door, self).write_to_block(block, offset, destination_locations) block[offset + 2] = DoorType.DOOR with Block() as destination_block: destination_block.from_list([0] * 11) self.text_pointer.to_block(destination_block, 0) destination_block.write_multi(4, self.flag, 2) destination_block[6] = self.destination_y & 0xff destination_block[7] = (self.destination_y >> 8) | (self.destination_direction << 6) destination_block.write_multi(8, self.destination_x, 2) destination_block[10] = self.destination_style self.write_destination_to_block(block, offset, destination_block, destination_locations) return 5 def yml_rep(self): out = super(Door, self).yml_rep() out["Type"] = DoorType.tostring(DoorType.DOOR) out["Text Pointer"] = self.text_pointer.yml_rep() out["Event Flag"] = EbEventFlagTableEntry.to_yml_rep(self.flag) out["Destination X"] = self.destination_x out["Destination Y"] = self.destination_y try: out["Direction"] = DestinationDirection.tostring(self.destination_direction) except InvalidArgumentError: raise InvalidUserDataError("Door had invalid destination direction of %#x" % self.destination_direction) out["Style"] = self.destination_style return out def from_yml_rep(self, yml_rep): super(Door, self).from_yml_rep(yml_rep) self.text_pointer.from_yml_rep(get_from_user_dict(yml_rep, "Text Pointer", str)) self.flag = EbEventFlagTableEntry.from_yml_rep(get_from_user_dict(yml_rep, "Event Flag", int)) self.destination_x = get_from_user_dict(yml_rep, "Destination X", int) self.destination_y = get_from_user_dict(yml_rep, "Destination Y", int) self.destination_direction = get_enum_from_user_dict(yml_rep, "Direction", DestinationDirection) self.destination_style = get_from_user_dict(yml_rep, "Style", int)