Keep ITEM_TREASURE_BOX/KEY and METIN_NORMAL rows; APPLY_ATTBONUS_STONE 139 / APPLY_ATTBONUS_BOSS 140 in ItemData.h, item module and tooltip (mt_applies). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
47 lines
3.5 KiB
Python
47 lines
3.5 KiB
Python
import sys,unittest
|
|
from pathlib import Path
|
|
HERE=Path(__file__).resolve().parents[1];sys.path.insert(0,str(HERE))
|
|
import make_items as m
|
|
READER=HERE.parents[3]/'metin2-server/src/server/db/src/ProtoReader.cpp'
|
|
|
|
def row(vnum,t,st,anti='NONE',flags='NONE',wear='NONE',applies=('APPLY_NONE','0')*3,values=('0',)*6,refine=('0','0')):
|
|
return [str(vnum),'x',t,st,'1',anti,flags,wear,'NONE','10','20',refine[0],refine[1],'0','LEVEL','120','LIMIT_NONE','0',*applies,*values,'0','0','-1','']
|
|
|
|
@unittest.skipUnless(READER.is_file(),'needs ../metin2-server')
|
|
class ConvertTests(unittest.TestCase):
|
|
E=m.enums(READER) if READER.is_file() else None
|
|
def test_weapon_kept_without_unknown_flags(self):
|
|
s,c,kept=m.convert(row(320,'ITEM_WEAPON','WEAPON_SWORD','ANTI_MUDANG | ANTI_WOLFMAN','ITEM_TUNABLE','WEAR_WEAPON',
|
|
('APPLY_ATT_SPEED','18','APPLY_ATTBONUS_BOSS','5','APPLY_NONE','0'),refine=('321','81')),self.E,{320})
|
|
self.assertTrue(kept);self.assertEqual(s[5],'ANTI_MUDANG');self.assertEqual(s[7],'WEAR_WEAPON')
|
|
self.assertEqual(s[18:22],['APPLY_ATT_SPEED','18','APPLY_ATTBONUS_BOSS','5']) # ported apply kept
|
|
self.assertEqual(s[11:13],['0','0']) # the +1 item is not imported
|
|
self.assertEqual(c[1:3],[self.E['type'].index('ITEM_WEAPON'),0]);self.assertEqual(c[4],1<<self.E['anti'].index('ANTI_MUDANG'))
|
|
self.assertEqual(len(s),33);self.assertEqual(len(c),31)
|
|
def test_costume_enchant_is_locked(self):
|
|
s,c,kept=m.convert(row(54001,'ITEM_USE','USE_CHANGE_ATTRIBUTE',flags='ITEM_STACKABLE',values=('23','10','2','0','0','0')),self.E,set())
|
|
self.assertFalse(kept);self.assertEqual(s[2:4],['ITEM_NONE','0']);self.assertEqual(s[24:30],['0']*6)
|
|
self.assertEqual(c[1:3],[0,0]);self.assertEqual(c[5],1<<self.E['flag'].index('ITEM_STACKABLE'))
|
|
def test_unknown_type_and_stackable_anti(self):
|
|
s,_,kept=m.convert(row(55010,'ITEM_PET','PET_SKILL','ITEM_STACKABLE','LOG','WEAR_PENDANT'),self.E,set())
|
|
self.assertFalse(kept);self.assertEqual(s[5:8],['NONE','LOG | ITEM_STACKABLE','NONE'])
|
|
def test_quest_subtype(self):
|
|
s,c,kept=m.convert(row(30400,'ITEM_QUEST','QUEST_NONE',values=('APPLY_NONE','0','0','0','0','0')),self.E,set())
|
|
self.assertTrue(kept);self.assertEqual(s[3],'0');self.assertEqual(s[24],'0')
|
|
def test_treasure_box_and_key_kept(self):
|
|
for vnum,t in ((77918,'ITEM_TREASURE_BOX'),(77921,'ITEM_TREASURE_KEY')):
|
|
s,c,kept=m.convert(row(vnum,t,'0',values=('3','0','0','0','0','0')),self.E,set())
|
|
self.assertTrue(kept);self.assertEqual(s[2:4],[t,'0']);self.assertEqual(s[24],'3') # key value0 == box value0 opens it
|
|
self.assertEqual(c[1],self.E['type'].index(t))
|
|
def test_stone_and_boss_stones_kept(self):
|
|
s,c,kept=m.convert(row(28444,'ITEM_METIN','METIN_NORMAL',flags='ITEM_STACKABLE',wear='WEAR_WEAPON',
|
|
applies=('APPLY_ATTBONUS_STONE','8','APPLY_NONE','0','APPLY_NONE','0'),values=('0','0','0','0','0','31')),self.E,set())
|
|
self.assertTrue(kept);self.assertEqual(s[7],'WEAR_WEAPON');self.assertEqual(s[18:20],['APPLY_ATTBONUS_STONE','8'])
|
|
self.assertEqual(c[17:19],[139,8]) # AVA2 numbering, shared with the server and client enums
|
|
self.assertEqual(self.E['apply'].index('APPLY_ATTBONUS_BOSS'),140);self.assertEqual(s[29],'31')
|
|
def test_names_cover_ranges(self):
|
|
n=m.names();self.assertEqual(len(n),478);self.assertEqual(n[54100],'武器外观强化石')
|
|
self.assertTrue(all(len(v.encode('gbk'))<=24 for v in n.values()))
|
|
|
|
if __name__=='__main__':unittest.main()
|