Ejemplo n.º 1
0
class TestEarItem(unittest.TestCase):
	def setUp(self):
		self.s = OBitStream()


	def test_short_name(self):
		self.item = EarItem("Simon")
		self.item.writeStream(self.s)
		b = self.s.getByteList()
		self.assertEquals("JM\x10\x00\xa1", ''.join(map(chr, b[:5])))

		with open(os.path.join(FILE_ROOT_DIR, "[Ear]Simon.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_over_long_name(self):
		self.assertRaises(ValueError, EarItem, "NoNameHasNoName")
Ejemplo n.º 2
0
class TestCharm(unittest.TestCase):
    def setUp(self):
        self.s = OBitStream()

    def test_charm_of_greed(self):
        item = Charm("cm1 ", 0x115)  # of greed
        item.setGfx(1)

        item.addProp(79)
        # +411%(9 bits) extra gold from monsters
        item.addProp(80)
        # +155%(8 bits) Better Chance of Getting Magic Items
        item.addProp(127)
        # +7 (3 bits) to All Skill Level
        item.addProp(239)
        # (6 bits) Extra Gold from Monsters (Based on Character Level)
        item.addProp(240)
        # (6 bits) Better Chance of Getting Magic Items (Based on Character Level)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 80 00 65",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[Charm]of_greed.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_charm_of_skill(self):
        item = Charm("cm1 ", 0x0f1)  # of Skill

        item.addProp(80)
        # +155%(8 bits) Better Chance of Getting Magic Items
        item.addProp(85)
        # +x% exp gain
        item.addProp(127)
        # +7 (3 bits) to All Skill Level
        item.addProp(240)
        # (6 bits) Better Chance of Getting Magic Items (Based on Character Level)

        # non-class skill (97), Valkyrie (32), level (+FF)
        item.addProp(97, 32, 0xFF)
        # non-class skill (97), Teleport (54), level (+FF)
        item.addProp(97, 54, 0xFF)

        # aura when equipped (151), Conviction (123), level (+31)
        item.addProp(151, 123, 0xFF)

        # cast level X "Lower Resist(91)" chance Y on striking
        item.addProp(198, 0xffff, 91, 0xffff)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 80 00 65",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[Charm]of_skill_aura_conviction.d2i"),
                "wb") as f:
            self.s.writeBytes(f)
Ejemplo n.º 3
0
 def setUp(self):
     self.stream = OBitStream()
Ejemplo n.º 4
0
class TestOBitStream(unittest.TestCase):
    def setUp(self):
        self.stream = OBitStream()

    def test_append_empty(self):
        self.assertEquals('', str(self.stream))
        self.assertEquals('', self.stream.toHexString())

    def test_append_zero_bit(self):
        self.stream.append(0xf, 0)
        self.assertEquals('', str(self.stream))
        self.assertEquals('', self.stream.toHexString())

    def test_append_one_bit(self):
        self.stream.append(1, 1)
        self.assertEquals('1', str(self.stream))
        self.assertEquals('01', self.stream.toHexString())

    def test_append_one_bit_extracted(self):
        self.stream.append(0xf, 1)
        self.assertEquals('1', str(self.stream))
        self.assertEquals('01', self.stream.toHexString())

    def test_append_8_bits(self):
        self.stream.append(0x76, 8)
        self.assertEquals('01110110'[::-1], str(self.stream))
        self.assertEquals('76', self.stream.toHexString())

    def test_append_9_bits(self):
        self.stream.append(0x176, 9)
        self.assertEquals('101110110'[::-1], str(self.stream))
        self.assertEquals('76 01', self.stream.toHexString())

    def test_append_9_bits_extracted(self):
        self.stream.append(0x776, 9)
        self.assertEquals('101110110'[::-1], str(self.stream))
        self.assertEquals('76 01', self.stream.toHexString())

    def test_append_32bits(self):
        self.stream.append(0x1F1F2F4F8, 32)
        self.assertEquals('11110001111100101111010011111000'[::-1],
                          str(self.stream))
        self.assertEquals('f8 f4 f2 f1', self.stream.toHexString())

    def test_append_3_2(self):
        self.stream.append(3, 3)
        self.stream.append(1, 2)
        self.assertEquals('01011'[::-1], str(self.stream))
        self.assertEquals('0b', self.stream.toHexString())

    def test_append_3_6_4(self):
        self.stream.append(int('001', 2), 3)
        self.stream.append(int('000011', 2), 6)
        self.stream.append(int('0111', 2), 4)
        self.assertEquals('0111000011001'[::-1], str(self.stream))
        self.assertEquals('19 0e', self.stream.toHexString())

    def test_append_string(self):
        self.stream.appendString("012 ")
        self.assertEquals('30 31 32 20', self.stream.toHexString())
        w = MemWriter()
        self.stream.writeBytes(w)
        self.assertEquals('30 31 32 20', str(w))

    def test_write_bytes(self):
        self.stream.append(int('1110101', 2), 7)
        self.assertEquals('75', self.stream.toHexString())
        w = MemWriter()
        self.stream.writeBytes(w)
        self.assertEquals('75', str(w))

    def test_write_bytes_long(self):
        self.stream.append(int('10100001111', 2), 11)
        self.assertEquals('0f 05', self.stream.toHexString())
        w = MemWriter()
        self.stream.writeBytes(w)
        self.assertEquals('0f 05', str(w))
Ejemplo n.º 5
0
class TestSetItem(unittest.TestCase):
    def setUp(self):
        self.s = OBitStream()

    def test_GriswoldsRedemption_scep(self):
        item = SetItem("7ws ", 0x53)
        item.addProp(91, 0)
        # requirment 0-100%

        item.addPropGroup("basicoffense")
        item.addProp(21)
        # +(6bits) min 1 hand dmg
        item.addProp(22)
        # +(7bits) max 1 hand dmg
        item.addProp(218)  #+%d to Maximum Damage (Based on Character Level)
        item.addProp(
            219)  #%d%% Enhanced Maximum Damage (Based on Character Level)
        item.addProp(135)  #%d%% Chance of Open Wounds
        item.addProp(136)  #%d%% Chance of Crushing Blow
        item.addProp(120, 0)  #%d(-128) to Monster Defense Per Hit

        # aura when equipped (151), Fanaticism (122), level (+31)
        item.addProp(151, 122, 0xFF)

        # cast level X "Frozen Orb(64)" chance Y on striking"
        item.addProp(198, 0xffff, 64, 0xffff)

        item.addSetProp(0, 188, 24, 0xff)  #Skills set X (24-PAL/Combat) +%d
        # item.addSetProp(0, 218) #+%d to Maximum Damage (Based on Character Level)
        # item.addSetProp(0, 219) #%d%% Enhanced Maximum Damage (Based on Character Level)

        # item.addSetProp(1, 218) #+%d to Maximum Damage (Based on Character Level)
        # item.addSetProp(1, 219) #%d%% Enhanced Maximum Damage (Based on Character Level)

        # item.addSetProp(2, 218) #+%d to Maximum Damage (Based on Character Level)
        # item.addSetProp(2, 219) #%d%% Enhanced Maximum Damage (Based on Character Level)

        item.writeStream(self.s)
        b = self.s.getByteList()
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[SetItem]griswolds_redemption_scep.d2i"),
                "wb") as f:
            self.s.writeBytes(f)

    def test_GriswoldsValor_helm(self):
        item = SetItem("urn ", 0x51)

        item.addPropGroup("basicdefense")
        item.addPropGroup("mf")

        # cast level X "Static Field (42)" chance Y on striking"
        item.addProp(198, 0xffff, 42, 0xffff)

        item.addSetProp(0, 188, 25,
                        0xff)  #Skills set X (25-PAL/OffensiveAura) +%d
        # item.addSetProp(1, 214) #+%d to Defense (Based on Character Level)
        # item.addSetProp(1, 215) #%d%% Enhanced Defense (Based on Character Level)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[SetItem]griswolds_valor_helm.d2i"), "wb") as f:
            self.s.writeBytes(f)

    def test_GriswoldsHeart_plate(self):
        item = SetItem("xar ", 0x52)

        item.addPropGroup("characteristic")
        item.addPropGroup("basicdefense")
        # item.addPropGroup("mf")
        # cast level X "Poison Nova(92)" chance Y on struck"
        item.addProp(201, 0xFFFF, 92, 0xFFFF)

        item.addProp(39)
        item.addProp(41)
        item.addProp(43)
        item.addProp(45)
        item.addProp(188, 26, 0xff)  #Skills set X (25-PAL/DefensiveAura) +%d

        # whether there were set props depends on game config!!!
        # item.addSetProp(0, 188, 26, 0xff) #Skills set X (25-PAL/DefensiveAura) +%d
        # item.addSetProp(0, 214) #+%d to Defense (Based on Character Level)
        # item.addSetProp(0, 215) #%d%% Enhanced Defense (Based on Character Level)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[SetItem]griswolds_heart_plate.d2i"), "wb") as f:
            self.s.writeBytes(f)

    def test_GriswoldsHonor_shield(self):
        item = SetItem("paf ", 0x54)

        item.addPropGroup("basicdefense")
        item.addPropGroup("mf")
        item.addProp(20)  #+x% Increased Chance of Blocking
        item.addProp(102)  #+x% Faster Block Rate

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[SetItem]griswolds_honor_shield.d2i"),
                "wb") as f:
            self.s.writeBytes(f)

    def test_CleglawsTooth_sword(self):
        item = SetItem("lsd ", 0x6)
        item.addProp(91, 0)
        # requirment 0-100%

        item.addPropGroup("basicoffense")
        item.addProp(21)
        # +(6bits) min 1 hand dmg
        item.addProp(22)
        # +(7bits) max 1 hand dmg

        # # aura when equipped (151), Fanaticism (122), level (+31)
        # item.addProp(151, 122, 0xFF)
        # aura when equipped (151), Holy Fire(102), level (+31)
        item.addProp(151, 102, 0xFF)

        # cast level X "Chain Lightning(53)" chance Y on striking"
        item.addProp(198, 0xffff, 53, 0xffff)

        item.addSetProp(0,
                        218)  #+%d to Maximum Damage (Based on Character Level)
        item.addSetProp(
            0, 219)  #%d%% Enhanced Maximum Damage (Based on Character Level)
        # item.addSetProp(0, 188, 24, 0xff) #Skills set X (24-PAL/Combat) +%d

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[SetItem]cleglaws_tooth_swor.d2i"), "wb") as f:
            self.s.writeBytes(f)

    def test_CleglawsClaw_shield(self):
        item = SetItem("sml ", 0x7)

        # item.addPropGroup("basicdefense")
        item.addProp(16)
        item.addProp(31)
        item.addProp(214)
        item.addProp(215)

        item.addProp(78)  #Attacker Takes Damage of %d
        item.addProp(81)  #Knockback
        item.addProp(102)  #+d% Faster Block Rate

        # aura when equipped (151), Thorns (103), level (+31)
        item.addSetProp(0, 151, 103, 0xFF)
        # item.addSetProp(0, 188, 26, 0xff) #Skills set X (26-PAL/DefensiveAura) +%d

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[SetItem]cleglaws_claw_shield.d2i"), "wb") as f:
            self.s.writeBytes(f)

    def test_CleglawsPincers_glove(self):
        item = SetItem("mgl ", 0x8)

        item.addPropGroup("mf")
        item.addProp(19)  #+d to Attack Rating
        item.addProp(119)  #+x% to Attack Rating
        item.addProp(150)  # Slows Target by x%

        item.addSetProp(0,
                        218)  #+%d to Maximum Damage (Based on Character Level)
        item.addSetProp(
            0, 219)  #%d%% Enhanced Maximum Damage (Based on Character Level)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(
                os.path.join(FILE_ROOT_DIR,
                             "[SetItem]cleglaws_pincers_glove.d2i"),
                "wb") as f:
            self.s.writeBytes(f)

    def test_CowKings_leather(self):
        item = SetItem("stu ", 0x76)

        item.addPropGroup("characteristic")
        item.addPropGroup("basicdefense")
        # item.addPropGroup("mf")
        # cast level X "Poison Nova(92)" chance Y on struck"
        item.addProp(201, 0xFFFF, 92, 0xFFFF)
        item.addProp(126, 3, 0xff)  # Poision(3) Skills +x
        # aura when equipped (151), Holy Fire(102), level (+31)
        item.addProp(151, 102, 0xFF)

        item.addProp(39)
        item.addProp(41)
        item.addProp(43)
        item.addProp(45)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]cowkings_leather.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_CowKings_hat(self):
        item = SetItem("xap ", 0x75)

        item.addPropGroup("basicdefense")
        item.addPropGroup("mf")

        # aura when equipped (151), Holy Shock(118), level (+31)
        item.addProp(151, 118, 0xFF)
        # cast level X "Static Field (42)" chance Y on striking"
        item.addProp(198, 0xffff, 42, 0xffff)
        item.addProp(126, 2, 0xff)  # Lightning(2) Skills +x

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]cowkings_hat.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_CowKings_boots(self):
        item = SetItem("vbt ", 0x77)

        item.addPropGroup("basicdefense")
        item.addPropGroup("mf")

        # aura when equipped (151), Vigor(115), level (+31)
        item.addProp(151, 115, 0xFF)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]cowkings_boots.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    # Assassin
    def test_Natalya_helm(self):
        item = SetItem("xh9 ", 0x3e)

        item.addProp(35)  # Magic Damage Reduced by %d
        # aura when equipped (151), Holy Shock(118), level (+31)
        item.addProp(151, 118, 0xFF)
        # cast level X "Static Field (42)" chance Y on striking"
        item.addProp(198, 0xffff, 42, 0xffff)
        item.addProp(330)  # +%d to Lightning Skill Damage

        # set item prop slot MUST follow game setting strictly!!!

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]natalya_helm.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_Natalya_scissors(self):
        item = SetItem("7qr ", 0x3f)

        item.addPropGroup("basicoffense")
        item.addProp(21)
        # +(6bits) min 1 hand dmg
        item.addProp(22)
        # +(7bits) max 1 hand dmg
        item.addProp(218)  #+%d to Maximum Damage (Based on Character Level)
        item.addProp(
            219)  #%d%% Enhanced Maximum Damage (Based on Character Level)

        # cast level X "Chain Lightning(53)" chance Y on striking"
        item.addProp(198, 0xffff, 53, 0xffff)
        item.addProp(330)  # +%d to Lightning Skill Damage

        item.addProp(188, 50, 0xff)  #Skills set X (24-ASS/MartialArt) +%d

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]natalya_scissors.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_Natalya_armor(self):
        item = SetItem("ucl ", 0x40)

        # item.addPropGroup("characteristic")
        item.addPropGroup("basicdefense")
        # item.addPropGroup("mf")
        # cast level X "Poison Nova(92)" chance Y on struck"
        item.addProp(201, 0xFFFF, 92, 0xFFFF)
        # aura when equipped (151), Holy Fire(102), level (+31)
        item.addProp(151, 102, 0xFF)
        item.addProp(329)  # x% to Fire Skill Damage
        item.addProp(332)  # +%d to Poison Skill Damage
        item.addProp(188, 49,
                     0xff)  #Skills set X (49-ASS/ShadowDiscipline) +%d

        item.addProp(39)
        item.addProp(41)
        item.addProp(43)
        item.addProp(45)
        # set item prop slot MUST follow game setting strictly!!!

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]natalya_armor.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_Natalya_boots(self):
        item = SetItem("xmb ", 0x41)

        item.addProp(67)  # Faster Run/Walk
        item.addProp(137)  # Kick Damage
        item.addProp(249)  # Kick Damage (Based on Character Level)
        item.addPropGroup("basicdefense")
        item.addPropGroup("mf")

        # aura when equipped (151), Vigor(115), level (+31)
        item.addProp(151, 115, 0xFF)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]natalya_boots.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    # Necromancer
    def test_TrangOuls_helm(self):
        item = SetItem("uh9 ", 0x55)

        item.addProp(78)  # Attacker Takes Damage of %d
        item.addProp(99)  # Faster Hit Recovery x%
        # aura when equipped (151), Holy Shock(118), level (+31)
        item.addProp(151, 118, 0xFF)
        # cast level X "Static Field (42)" chance Y on striking"
        item.addProp(198, 0xffff, 42, 0xffff)
        item.addProp(330)  # +%d to Lightning Skill Damage
        item.addProp(329)  # x% to Fire Skill Damage

        # set item prop slot MUST follow game setting strictly!!!

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]trangouls_helm.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_TrangOuls_armor(self):
        item = SetItem("xul ", 0x56)

        # item.addPropGroup("characteristic")
        item.addPropGroup("basicdefense")
        # item.addPropGroup("mf")
        # cast level X "Poison Nova(92)" chance Y on struck"
        item.addProp(201, 0xFFFF, 92, 0xFFFF)
        # aura when equipped (151), Holy Fire(102), level (+31)
        item.addProp(151, 102, 0xFF)

        # set item prop slot MUST follow game setting strictly!!!
        item.addSetProp(1, 39)
        item.addSetProp(1, 41)
        item.addSetProp(1, 43)
        item.addSetProp(1, 45)

        item.addSetProp(3, 36)  # Damage Reduced by x%

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]trangouls_armor.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_TrangOuls_trophy(self):
        item = SetItem("ne9 ", 0x57)

        item.addProp(20)  # x% Increased Chance of Blocking
        item.addProp(102)  # +d% Faster Block Rate
        item.addProp(188, 17, 0xff)  #Skills set X (17-NEC/PosionAndBone) +%d

        # set item prop slot MUST follow game setting strictly!!!
        item.addSetProp(1, 336)  # x% to Enemy Poison Resistance
        # aura when equipped (151), Thorns (103), level (+31)
        item.addSetProp(2, 151, 103, 0xFF)

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 08 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]trangouls_trophy.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_TrangOuls_gloves(self):
        item = SetItem("xmg ", 0x58)

        item.addPropGroup("mf")
        item.addProp(105)  # x% Faster Cast Rate
        item.addProp(229)  # +%d Poison Damage (Based on Character Level)
        item.addProp(332)  # +%d to Poison Skill Damage

        # set item prop slot MUST follow game setting strictly!!!

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]trangouls_gloves.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)

    def test_TrangOuls_belt(self):
        item = SetItem("utc ", 0x59)

        item.addProp(7)  # +d Life
        item.addProp(9)  # +d Mana
        item.addProp(11)  # +d Maximum Stamina
        item.addProp(74)  # Replenish Life +%d
        item.addProp(76)  # x% Max Life
        item.addProp(77)  # x% Max Mana
        # item.addPropGroup("mf")

        # set item prop slot MUST follow game setting strictly!!!
        item.addSetProp(1, 153)  # Cannot Be Frozen

        item.writeStream(self.s)
        self.assertEquals("4a 4d 10 00 c0 00 64",
                          self.s.toHexString()[:7 * 3 - 1])

        with open(os.path.join(FILE_ROOT_DIR, "[SetItem]trangouls_belt.d2i"),
                  "wb") as f:
            self.s.writeBytes(f)
Ejemplo n.º 6
0
class TestUniqItem(unittest.TestCase):
	def setUp(self):
		self.s = OBitStream()


	def test_amu_of_rixots_keen(self):
		item = UniqItem("amu ", 25) # Rixot's

		item.addPropGroup("characteristic")
		item.addPropGroup("mf")
		item.addPropGroup("defense")

		item.writeStream(self.s)
		result = str(self.s)
		self.assertEquals("1", result[20])
		self.assertEquals("4a 4d 10 00 80 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]amulet_of_rixots_keen.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_ring_nagelring(self):
		item = UniqItem("rin ", 0x78) # Nagelring

		item.addPropGroup("mf")
		item.addProp(127); # +7 (3 bits) to All Skill Level

		item.writeStream(self.s)
		self.assertEquals("4a 4d 10 00 80 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]ring_of_nagelring.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_tors_of_blinkbats_form(self):
		item = UniqItem("lea ", 80)

		item.addPropGroup("characteristic")
		item.addPropGroup("mf")
		item.addPropGroup("defense")

		# cast level X "Poison Nova(92)" chance Y on struck"
		item.addProp(201, 0xFFFF, 92, 0xFFFF)

		item.writeStream(self.s)
		self.assertEquals("4a 4d 10 08 c0 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]tors_of_blinkbats_form.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_pole_of_soul_harvest(self):
		# SourHarvest in game is "scy ", not sure "hal " would always work!!!
		item = UniqItem("hal ", 0x32)

		item.addProp(91, 0); # requirment 0-100%
		item.addProp(23); # +(6bits) min 2 hands dmg
		item.addProp(24); # +(7bits) max 2 hands dmg
		item.addPropGroup("offense")

		# aura when equipped (151), Holy Shock(118), level (+31)
		item.addProp(151, 118, 0xFF)

		# cast level X "Meteor(56)" chance Y on striking"
		item.addProp(198, 0xffff, 56, 0xffff)

		item.writeStream(self.s)
		self.assertEquals("4a 4d 10 08 c0 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]pole_of_soulharvest.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_bow_of_KukoShakaku(self):
		item = UniqItem("8lb ", 0xbe)

		item.addProp(91, 0); # requirment 0-100%
		item.addProp(23); # +(6bits) min 2 hands dmg
		item.addProp(24); # +(7bits) max 2 hands dmg
		item.addPropGroup("offense")

		# aura when equipped (151), Holy Shock(118), level (+31)
		item.addProp(151, 118, 0xFF)

		# cast level X "Meteor(56)" chance Y on striking"
		item.addProp(198, 0xffff, 56, 0xffff)

		item.writeStream(self.s)
		self.assertEquals("4a 4d 10 08 c0 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]bow_of_kKukoShakaku.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_bow_of_Pluckeye(self):
		# "sbb " => Stormstrike(0x3f), reqLvl=23
		# "sbw " => Pluckeys(0x3b), reqLvl=7
		item = UniqItem("sbb ", 0x3b) # "sbw " => "sbb "

		item.addProp(91, 0); # requirment 0-100%
		item.addProp(23); # +(6bits) min 2 hands dmg
		item.addProp(24); # +(7bits) max 2 hands dmg
		item.addPropGroup("offense")

		# aura when equipped (151), Holy Shock(118), level (+31)
		item.addProp(151, 118, 0xFF)

		# cast level X "Meteor(56)" chance Y on striking"
		item.addProp(198, 0xffff, 56, 0xffff)

		item.writeStream(self.s)
		self.assertEquals("4a 4d 10 08 c0 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]bow_of_pluckeye.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_javelin_of_Pluckeye(self):
		item = UniqItem("tsp ", 25)

		item.addProp(91, 0); # requirment 0-100%
		item.addProp(23); # +(6bits) min 2 hands dmg
		item.addProp(24); # +(7bits) max 2 hands dmg
		item.addPropGroup("offense")
		item.addProp(159) # +d to min Throw Damage
		item.addProp(160) # +d to max Throw Damage

		# aura when equipped (151), Holy Shock(118), level (+31)
		item.addProp(151, 118, 0xFF)

		# cast level X "Chain Lightning(53)" chance Y on striking"
		item.addProp(198, 0xffff, 53, 0xffff)

		item.writeStream(self.s)
		self.assertEquals("4a 4d 10 00 c0 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]javelin.d2i"), "wb") as f:
			self.s.writeBytes(f)

	def test_claw_of_Pluckeye(self):
		item = UniqItem("skr ", 25)
		item.addProp(91, 0); # requirment 0-100%

		item.addPropGroup("basicoffense")
		item.addProp(21); # +(6bits) min 1 hand dmg
		item.addProp(22); # +(7bits) max 1 hand dmg
		item.addProp(218) #+%d to Maximum Damage (Based on Character Level)
		item.addProp(219) #%d%% Enhanced Maximum Damage (Based on Character Level)

		# cast level X "Chain Lightning(53)" chance Y on striking"
		item.addProp(198, 0xffff, 53, 0xffff)


		item.writeStream(self.s)
		self.assertEquals("4a 4d 10 08 c0 00 64", self.s.toHexString()[:7*3-1])

		with open(os.path.join(FILE_ROOT_DIR, "[UniqItem]claw.d2i"), "wb") as f:
			self.s.writeBytes(f)