AVA2 unlock P7: talismans (护符) and their attribute items

- ARMOR_PENDANT / APPLY_ENCHANT_* 123-128 / c_Equipment_Pendant (server WEAR_PENDANT 27) constants
- mt_pendant: equipment slot under the earring, drop targets for 71302/53996 (reroll) and 71301/53997
  (add, max 5), MTPENDANT messages; enchant apply texts in mt_applies
- switchbot ignores talismans and talisman rerolls
- make_items keeps the six +0..+200 chains (1206 items) and the four attribute items
- tools/server/pendant: refine sets 440-499 (AVA2 rows) + install.sh

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-10-16 14:26:12 +09:00
co-authored by Claude Opus 5.5
parent a1b63c0afb
commit b9af78ef64
13 changed files with 249 additions and 12 deletions
+13 -2
View File
@@ -22,7 +22,7 @@ class ConvertTests(unittest.TestCase):
for vnum,mask in ((54001,'2'),(54078,'4'),(54130,'16')): # body / hair / mount skin (port_costume_attr.cpp)
s,c,kept=m.convert(row(vnum,'ITEM_USE','USE_CHANGE_ATTRIBUTE',flags='ITEM_STACKABLE',values=('23','10',mask,'0','0','0')),self.E,set())
self.assertTrue(kept);self.assertEqual(s[2:4],['ITEM_USE','USE_CHANGE_ATTRIBUTE']);self.assertEqual(s[24:27],['23','10',mask])
for vnum,mask in ((54100,'8'),(54200,'32'),(54250,'64'),(53996,'0')): # weapon costume / sash skin / effect / talisman
for vnum,mask in ((54100,'8'),(54200,'32'),(54250,'64')): # weapon costume / sash skin / effect
s,c,kept=m.convert(row(vnum,'ITEM_USE','USE_CHANGE_ATTRIBUTE',flags='ITEM_STACKABLE',values=('23','10',mask,'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'))
@@ -63,6 +63,17 @@ class ConvertTests(unittest.TestCase):
s,c,kept=m.convert(row(71234,'ITEM_COSTUME','COSTUME_MOUNT_SKIN',values=('32012','0','0','0','0','0')),self.E,{71234})
self.assertTrue(kept);self.assertEqual(s[3],'COSTUME_MOUNT_SKIN');self.assertEqual(c[2],4)
self.assertEqual(set(m.MOUNT_MOBS),{32012,32028})
def test_pendant_and_scrolls_kept(self):
s,c,kept=m.convert(row(9601,'ITEM_ARMOR','ARMOR_PENDANT',flags='ITEM_TUNABLE',wear='WEAR_PENDANT',
applies=('APPLY_ENCHANT_FIRE','1','APPLY_NONE','0','APPLY_NONE','0'),refine=('9602','441')),self.E,{9601,9602})
self.assertTrue(kept);self.assertEqual(s[3],'ARMOR_PENDANT');self.assertEqual(s[7],'NONE') # no WEAR_PENDANT flag: FindEquipCell
self.assertEqual(s[11:13],['9602','441']);self.assertEqual(s[18:20],['APPLY_ENCHANT_FIRE','1']);self.assertEqual(c[17],124)
self.assertEqual(c[2],self.E['sub'][self.E['type'].index('ITEM_ARMOR')].index('ARMOR_PENDANT'))
for vnum,st in ((53996,'USE_CHANGE_ATTRIBUTE'),(71302,'USE_CHANGE_ATTRIBUTE'),(53997,'USE_ADD_ATTRIBUTE'),(71301,'USE_ADD_ATTRIBUTE')):
s,c,kept=m.convert(row(vnum,'ITEM_USE',st,flags='ITEM_STACKABLE'),self.E,set())
self.assertTrue(kept);self.assertEqual(s[2:4],['ITEM_USE',st])
s,c,kept=m.convert(row(71303,'ITEM_USE','USE_ADD_ATTRIBUTE'),self.E,set());self.assertFalse(kept)
n=m.names();self.assertEqual([n[v] for v in (9600,9800,10950)],['火之护符+0','火之护符+200','雷之护符+200'])
def test_install_items_with_mobs(self):
import subprocess,tempfile
with tempfile.TemporaryDirectory() as d:
@@ -91,7 +102,7 @@ class ConvertTests(unittest.TestCase):
with self.assertRaises(SystemExit):m.effect_files(files)
def test_names_cover_ranges(self):
n=m.names();self.assertEqual(len(n),514);self.assertEqual(n[54100],'武器外观强化石')
n=m.names();self.assertEqual(len(n),514+6*200);self.assertEqual(n[54100],'武器外观强化石')
self.assertEqual([n[v] for v in (21210,21219,21279)],['暗龙铠甲+0','暗龙铠甲+9','神龙铠甲+9'])
self.assertTrue(all(len(v.encode('gbk'))<=24 for v in n.values()))